<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>Roman Cheplyaka</title>
        <link>http://ro-che.info/articles/</link>
        <description>Articles by Roman Cheplyaka</description>
        <atom:link href="https://ro-che.info/articles/rss.xml" rel="self" type="application/rss+xml" />
        
                <item>
                        <title>Рейтинги шахових розрядів і звань</title>
                        <description>&lt;p&gt;Якщо ви переважно граєте в шахи онлайн, ви могли задаватися питанням,
якому шаховому розряду або званню відповідає ваш рівень гри.&lt;/p&gt;
&lt;p&gt;Отже, я провів невеличкий аналіз, щоб визначити приблизний діапазон
рейтингів FIDE, який відповідає кожному розряду і званню в Україні.
Оцінити свій рейтинг FIDE можна, скориставшись &lt;a
href=&quot;https://www.chessmonitor.com/&quot;&gt;chessmonitor.com&lt;/a&gt; або &lt;a
href=&quot;https://chess-analysis.org/rating-converter&quot;&gt;chess-analysis.org&lt;/a&gt;.&lt;/p&gt;
&lt;table&gt;
&lt;tr&gt;
&lt;th&gt;
Розряд/звання
&lt;/th&gt;
&lt;th&gt;
Від (10%)
&lt;/th&gt;
&lt;th&gt;
Медіана
&lt;/th&gt;
&lt;th&gt;
До (90%)
&lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
III розряд
&lt;/td&gt;
&lt;td&gt;
1410
&lt;/td&gt;
&lt;td&gt;
1440
&lt;/td&gt;
&lt;td&gt;
1470
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
II розряд
&lt;/td&gt;
&lt;td&gt;
1430
&lt;/td&gt;
&lt;td&gt;
1500
&lt;/td&gt;
&lt;td&gt;
1600
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
I розряд
&lt;/td&gt;
&lt;td&gt;
1480
&lt;/td&gt;
&lt;td&gt;
1640
&lt;/td&gt;
&lt;td&gt;
1890
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
Кандидат у майстри спорту
&lt;/td&gt;
&lt;td&gt;
1820
&lt;/td&gt;
&lt;td&gt;
2000
&lt;/td&gt;
&lt;td&gt;
2230
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
Майстер спорту
&lt;/td&gt;
&lt;td&gt;
1970
&lt;/td&gt;
&lt;td&gt;
2190
&lt;/td&gt;
&lt;td&gt;
2320
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
Міжнародний майстер
&lt;/td&gt;
&lt;td&gt;
2080
&lt;/td&gt;
&lt;td&gt;
2330
&lt;/td&gt;
&lt;td&gt;
2440
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
Міжнародний гросмейстер
&lt;/td&gt;
&lt;td&gt;
2240
&lt;/td&gt;
&lt;td&gt;
2480
&lt;/td&gt;
&lt;td&gt;
2600
&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;figure&gt;
&lt;img src=&quot;/img/chess-titles-ratings.svg&quot;
alt=&quot;80% інтервал та розподіл рейтингів FIDE для кожного розряду і звання&quot; /&gt;
&lt;figcaption aria-hidden=&quot;true&quot;&gt;80% інтервал та розподіл рейтингів FIDE
для кожного розряду і звання&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Джерела даних:&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;&lt;a
href=&quot;https://ukrchess.org.ua/kvalif/2026/03/rating.html&quot;&gt;Рейтинг-лист
шахістів України на 1 березня 2026 року Федерації шахів України&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Рейтинг-лист шахістів Прикарпаття до 18 років на жовтень 2025 року,
зібраний Михайлом Кепещуком&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Якщо ви маєте доступ до інших масивів даних (зокрема, даних по
розрядах в інших регіонах України), зв’яжіться зі мною, це допоможе
зробити аналіз більш повним та точним.&lt;/p&gt;
&lt;p&gt;Більше про присвоєння спортивних звань та розрядів з шахів в Україні
можна дізнатися тут: &lt;a
href=&quot;https://www.ukrchess.org.ua/kvalif/esku_2023.pdf&quot;&gt;Додаток 116 до
Кваліфікаційних норм та вимог Єдиної спортивної класифікації України з
неолімпійських видів спорту&lt;/a&gt;.&lt;/p&gt;
</description>
                        <pubDate>Sun, 05 Apr 2026 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2026-04-05-%D1%80%D0%B5%D0%B9%D1%82%D0%B8%D0%BD%D0%B3%D0%B8-%D1%88%D0%B0%D1%85%D0%BE%D0%B2%D0%B8%D1%85-%D1%80%D0%BE%D0%B7%D1%80%D1%8F%D0%B4%D1%96%D0%B2-%D1%96-%D0%B7%D0%B2%D0%B0%D0%BD%D1%8C</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2026-04-05-%D1%80%D0%B5%D0%B9%D1%82%D0%B8%D0%BD%D0%B3%D0%B8-%D1%88%D0%B0%D1%85%D0%BE%D0%B2%D0%B8%D1%85-%D1%80%D0%BE%D0%B7%D1%80%D1%8F%D0%B4%D1%96%D0%B2-%D1%96-%D0%B7%D0%B2%D0%B0%D0%BD%D1%8C.html</guid>
                </item>
        
                <item>
                        <title>Alice and Bob flipping coins puzzle</title>
                        <description>&lt;p&gt;Daniel Litt on Twitter suggests a puzzle with a surprising
answer:&lt;/p&gt;
&lt;blockquote class=&quot;twitter-tweet&quot;&gt;
&lt;p lang=&quot;en&quot; dir=&quot;ltr&quot;&gt;
Flip a fair coin 100 times—it gives a sequence of heads (H) and tails
(T). For each HH in the sequence of flips, Alice gets a point; for each
HT, Bob does, so e.g. for the sequence THHHT Alice gets 2 points and Bob
gets 1 point. Who is most likely to win?
&lt;/p&gt;
— Daniel Litt (&lt;span class=&quot;citation&quot;
data-cites=&quot;littmath&quot;&gt;@littmath&lt;/span&gt;)
&lt;a href=&quot;https://twitter.com/littmath/status/1769044719034647001&quot;&gt;March
16, 2024&lt;/a&gt;
&lt;/blockquote&gt;
&lt;p&gt;Like many others, I intuitively assumed the answer would be Alice,
since her winning segments can overlap, while Bob’s can’t. And yet the
right answer is Bob:&lt;/p&gt;
&lt;blockquote class=&quot;twitter-tweet&quot;&gt;
&lt;p lang=&quot;en&quot; dir=&quot;ltr&quot;&gt;
The correct answer is “Bob.” Congrats to the 10% who got it right —
those few brave dreamers.
&lt;figure&gt;
&lt;img src=&quot;/img/alice-bob-flipping-coins/poll.jpeg&quot; alt=&quot;A screenshot of the results of the Twitter poll with the results: Alice 26%, Bob 10%, Equally likely 43%, See results 21%&quot;/&gt;
&lt;/figure&gt;
&lt;/p&gt;
— Daniel Litt (&lt;span class=&quot;citation&quot;
data-cites=&quot;littmath&quot;&gt;@littmath&lt;/span&gt;)
&lt;a href=&quot;https://twitter.com/littmath/status/1769408478139785497&quot;&gt;March
17, 2024&lt;/a&gt;
&lt;/blockquote&gt;
&lt;p&gt;To figure out the answer, let’s represent the game as the following
Markov chain:&lt;/p&gt;
&lt;figure&gt;
&lt;img src=&quot;/img/alice-bob-flipping-coins/states.png&quot;
alt=&quot;Markov chain transition diagram&quot; /&gt;
&lt;figcaption aria-hidden=&quot;true&quot;&gt;Markov chain transition
diagram&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;We start at &lt;span class=&quot;math inline&quot;&gt;\(S_1\)&lt;/span&gt;, and every time
a coin is flipped, we move to another state according to the diagram.
When we reach state &lt;span class=&quot;math inline&quot;&gt;\(S_3,\)&lt;/span&gt; Alice gets
a point, and when we reach &lt;span class=&quot;math inline&quot;&gt;\(S_4,\)&lt;/span&gt; Bob
gets a point.&lt;/p&gt;
&lt;p&gt;The transition matrix for this Markov chain is&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;math display&quot;&gt;\[
\begin{pmatrix}
0.5 &amp;amp; 0.5 &amp;amp; 0 &amp;amp; 0 \\
0 &amp;amp; 0 &amp;amp; 0.5 &amp;amp; 0.5 \\
0 &amp;amp; 0 &amp;amp; 0.5 &amp;amp; 0.5 \\
0.5 &amp;amp; 0.5 &amp;amp; 0 &amp;amp; 0
\end{pmatrix}
= 0.5 \cdot
\begin{pmatrix}
1 &amp;amp; 1 &amp;amp; 0 &amp;amp; 0 \\
0 &amp;amp; 0 &amp;amp; 1 &amp;amp; 1 \\
0 &amp;amp; 0 &amp;amp; 1 &amp;amp; 1 \\
1 &amp;amp; 1 &amp;amp; 0 &amp;amp; 0
\end{pmatrix}.
\]&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;While raising this matrix to the &lt;span
class=&quot;math inline&quot;&gt;\(n\)&lt;/span&gt;th power would allow us to compute the
probabilities of ending up in different states after &lt;span
class=&quot;math inline&quot;&gt;\(n\)&lt;/span&gt; steps, this is not enough to keep track
of Alice’s and Bob’s scores. For that, let’s multiply the transition
probabilities by &lt;span class=&quot;math inline&quot;&gt;\(x\)&lt;/span&gt; if Alice gets a
point after a transition to that state and by &lt;span
class=&quot;math inline&quot;&gt;\(x^{-1}\)&lt;/span&gt; if Bob does. Our matrix is
then&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;math display&quot;&gt;\[A
= 0.5 \cdot
\begin{pmatrix}
1 &amp;amp; 1 &amp;amp; 0 &amp;amp; 0 \\
0 &amp;amp; 0 &amp;amp; x &amp;amp; x^{-1} \\
0 &amp;amp; 0 &amp;amp; x &amp;amp; x^{-1} \\
1 &amp;amp; 1 &amp;amp; 0 &amp;amp; 0
\end{pmatrix}.
\]&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Transition probabilities computed using such a matrix are Laurent
polynomials in &lt;span class=&quot;math inline&quot;&gt;\(x\)&lt;/span&gt;, &lt;span
class=&quot;math inline&quot;&gt;\(\sum a_k x^k\)&lt;/span&gt;, where &lt;span
class=&quot;math inline&quot;&gt;\(a_k\)&lt;/span&gt; is the probability of arriving at the
given state and having Alice earn &lt;span class=&quot;math inline&quot;&gt;\(k\)&lt;/span&gt;
more points than Bob. So to answer the original question, we need to see
whether the sum of the coefficients of &lt;span
class=&quot;math inline&quot;&gt;\(x^k\)&lt;/span&gt; for &lt;span
class=&quot;math inline&quot;&gt;\(k&amp;gt;0\)&lt;/span&gt; is more, less, or equal to the sum
of the coefficients of &lt;span class=&quot;math inline&quot;&gt;\(x^k\)&lt;/span&gt; for
negative &lt;span class=&quot;math inline&quot;&gt;\(k\)&lt;/span&gt; after 100 steps. Since
we start at &lt;span class=&quot;math inline&quot;&gt;\(S_1\)&lt;/span&gt; and can finish in
any state, the polynomial of interest is the sum of the first row of
&lt;span class=&quot;math inline&quot;&gt;\(A^{100}\)&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;To summarize, if&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;math display&quot;&gt;\[
P_{100}(x) =
\begin{pmatrix} 1 &amp;amp; 0 &amp;amp; 0 &amp;amp; 0 \end{pmatrix} \cdot A^{100}
\cdot \begin{pmatrix} 1 \\ 1 \\ 1 \\ 1 \end{pmatrix}
= \sum_{k &amp;gt; 0} a_k x^k + \sum_{k &amp;gt; 0} b_k x^{-k} + c,
\]&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;then &lt;span class=&quot;math inline&quot;&gt;\(\sum a_k\)&lt;/span&gt; is the probability
of Alice’s win, &lt;span class=&quot;math inline&quot;&gt;\(\sum b_k\)&lt;/span&gt; is the
probability of Bob’s win, and &lt;span class=&quot;math inline&quot;&gt;\(c\)&lt;/span&gt; is
the probability of a tie.&lt;/p&gt;
&lt;p&gt;For the record, &lt;span class=&quot;math inline&quot;&gt;\(P_{100}(x)\)&lt;/span&gt;
is:&lt;/p&gt;
&lt;pre class=&quot;polynomial&quot;&gt;
0.5^100 (x^-50 + 1325 x^-49 + 294050 x^-48 + 26617290 x^-47 + 1330255815 x^-46 + 42919935835 x^-45 + 983156559210 x^-44 + 17033316749820 x^-43 + 233400608147735 x^-42 + 2614381239414735 x^-41 + 24550574713787010 x^-40 + 197150946519643550 x^-39 + 1375679410685414450 x^-38 + 8451073972164127108 x^-37 + 46210399961145343413 x^-36 + 227004362149489184022 x^-35 + 1009860516432421484187 x^-34 + 4096712177858121360399 x^-33 + 15247749308938974542421 x^-32 + 52350824044788156054216 x^-31 + 166607171077709190756060 x^-30 + 493645720376366009163516 x^-29 + 1367143433188619109053352 x^-28 + 3551954012109459164577376 x^-27 + 8686109884277283187997106 x^-26 + 20055225149893348816333554 x^-25 + 43844627549786945958589680 x^-24 + 91001422499460503626585260 x^-23 + 179763829541066577971612952 x^-22 + 338757354861894875655388932 x^-21 + 610315290987050592852426198 x^-20 + 1053386609896119310058220228 x^-19 + 1745118407135736558029089726 x^-18 + 2780043435628079169902430486 x^-17 + 4265870818552696769971996446 x^-16 + 6315241299298077313067374248 x^-15 + 9033468660829178932648222012 x^-14 + 12503156034451523603337781244 x^-13 + 16767474523347110492502105992 x^-12 + 21814598828347171620337357152 x^-11 + 27566098692592563661052910714 x^-10 + 33871849156423377148712374730 x^-9 + 40513231768576837533202703640 x^-8 + 47215173793461455702590625004 x^-7 + 53666145312218517883076816204 x^-6 + 59543892735365660957139789376 x^-5 + 64543704258920714616943515626 x^-4 + 68405570616760641713507980732 x^-3 + 70936793516426715075493432331 x^-2 + 72027343751505931141583428951 x^-1 + 71656412569848144755925222552 + 69889902879368773013173398330 x^1 + 66869833498941600008977020285 x^2 + 62797584077826886590138297533 x^3 + 57913469629702003919294540728 x^4 + 52475267875032276436535696432 x^5 + 46738074687809409100604254222 x^6 + 40937334350174219405131043774 x^7 + 35276210892780037700873584024 x^8 + 29917762478918476882474277364 x^9 + 24981757635389467855166986572 x^10 + 20545499627554709440186102728 x^11 + 16647734116451790331493872286 x^12 + 13294601803478278796908527364 x^13 + 10466633422619434205715329714 x^14 + 8125926604510988498320158730 x^15 + 6222846658893522578565699494 x^16 + 4701814476526100204432324608 x^17 + 3505952179066875448077681428 x^18 + 2580529813081249595335291068 x^19 + 1875284165409224711691937404 x^20 + 1345762480733919638881619816 x^21 + 953884541799647548467422492 x^22 + 667924788912881555961042316 x^23 + 462101645635764580234757556 x^24 + 315933195502895341298309504 x^25 + 213484478528509628644574020 x^26 + 142597606903299702697618140 x^27 + 94165295328566214405929076 x^28 + 61483190066811250498536216 x^29 + 39697162852338816024840079 x^30 + 25348214742043061522139419 x^31 + 16008996325093659482849398 x^32 + 10001161522302185560020758 x^33 + 6180791128771176344008963 x^34 + 3779023811996709991594019 x^35 + 2286066208917365558991896 x^36 + 1368359999967026032354752 x^37 + 810476154998045342538654 x^38 + 475041466638122452084414 x^39 + 275546274649221072591904 x^40 + 158178293697206665493492 x^41 + 89867648637382149651024 x^42 + 50533126782451168142548 x^43 + 28123845113051129416418 x^44 + 15491932054735130750508 x^45 + 8446422906616520626494 x^46 + 4558036012110548547798 x^47 + 2434549498994866786034 x^48 + 1287036656999057467424 x^49 + 673422983571685912648 x^50 + 348737888851294898280 x^51 + 178735377499734476360 x^52 + 90658265801360274016 x^53 + 45506194887963205806 x^54 + 22603387487011330494 x^55 + 11109477277752161064 x^56 + 5402634939088716388 x^57 + 2599348281853560988 x^58 + 1237186710532642568 x^59 + 582504495903896934 x^60 + 271258374586669636 x^61 + 124915774672520357 x^62 + 56888561881025689 x^63 + 25615767980815224 x^64 + 11399249487823014 x^65 + 5014926877132547 x^66 + 2180915576957059 x^67 + 936384359299208 x^68 + 397188128932528 x^69 + 166612052646818 x^70 + 68893011316114 x^71 + 28088731372888 x^72 + 11348888534124 x^73 + 4513130425164 x^74 + 1759354998368 x^75 + 683049732010 x^76 + 261506110220 x^77 + 96634341361 x^78 + 35818805501 x^79 + 13299438184 x^80 + 4606342574 x^81 + 1599386433 x^82 + 586908453 x^83 + 189264458 x^84 + 58562524 x^85 + 21967781 x^86 + 6714397 x^87 + 1655690 x^88 + 664210 x^89 + 206498 x^90 + 32856 x^91 + 14727 x^92 + 5330 x^93 + 390 x^94 + 198 x^95 + 101 x^96 + 2 x^97 + x^98 + x^99)
&lt;/pre&gt;
&lt;p&gt;Tallying up the coefficients, Alice wins with probability &lt;span
class=&quot;math inline&quot;&gt;\(580127949239420834381088427404/2^{100} ≈
0.4576\)&lt;/span&gt;, Bob wins with probability &lt;span
class=&quot;math inline&quot;&gt;\(615866238418960422359689555420/2^{100} ≈
0.4858\)&lt;/span&gt;, and there is a tie with probability &lt;span
class=&quot;math inline&quot;&gt;\(71656412569848144755925222552/2^{100} ≈
0.0565\)&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;Here are the outcome probabilities for different numbers of tosses
(cf. the simulation results &lt;a
href=&quot;https://twitter.com/jkarttunen/status/1769315908701261842&quot;&gt;here&lt;/a&gt;).&lt;/p&gt;
&lt;!-- https://twitter.com/alexselby1770/status/1769795987344638033 --&gt;
&lt;figure&gt;
&lt;img src=&quot;/img/alice-bob-flipping-coins/probs.svg&quot;
alt=&quot;Outcome probabilities for different numbers of total coin tosses&quot; /&gt;
&lt;figcaption aria-hidden=&quot;true&quot;&gt;Outcome probabilities for different
numbers of total coin tosses&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;The Haskell code for computing the probabilities is available &lt;a
href=&quot;/files/2024-03-18-alice-bob-coin-flipping/alice.hs.html&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;See also: &lt;a href=&quot;https://arxiv.org/abs/2405.16660&quot;&gt;A proof that HT
is more likely to outnumber HH than vice versa in a sequence of n coin
flips&lt;/a&gt;.&lt;/p&gt;
</description>
                        <pubDate>Mon, 18 Mar 2024 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2024-03-18-alice-bob-coin-flipping</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2024-03-18-alice-bob-coin-flipping.html</guid>
                </item>
        
                <item>
                        <title>Sum of random cards puzzle</title>
                        <description>&lt;p&gt;Here’s a nice puzzle, via &lt;a
href=&quot;https://mathstodon.xyz/@christianp/111628329040458522&quot;&gt;Christian
Lawson-Perfect&lt;/a&gt; and &lt;a
href=&quot;https://blog.tanyakhovanova.com/2023/12/a-probability-puzzle-from-facebook/&quot;&gt;Tanya
Khovanova&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;There are 100 cards with integers from 1 to 100. You have three
possible scenarios: you pick 18, 19, or 20 cards at random. For each
scenario, you need to estimate the probability that the sum of the cards
is even. You do not need to do the exact calculation; you just need to
say whether the probability is less than, equal to, or more than
1/2.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;solution&quot;&gt;Solution&lt;/h2&gt;
&lt;p&gt;For a card with the number &lt;span class=&quot;math inline&quot;&gt;\(k\)&lt;/span&gt;,
construct the term &lt;span class=&quot;math inline&quot;&gt;\(a(k) = 1 +
(-1)^kx\)&lt;/span&gt;, and consider the product of these terms for all the
cards:&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;math display&quot;&gt;\[
A=a(1)a(2)\cdots a(100)=(1-x)^{50}(1+x)^{50}.
\]&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;The expansion of this product consists of &lt;span
class=&quot;math inline&quot;&gt;\(2^{100}\)&lt;/span&gt; monomials of the form &lt;span
class=&quot;math inline&quot;&gt;\((-1)^{k_1+k_2+\cdots+k_n}x^n\)&lt;/span&gt;, and each
such monomial corresponds to a unique combination of &lt;span
class=&quot;math inline&quot;&gt;\(n\)&lt;/span&gt; cards &lt;span class=&quot;math inline&quot;&gt;\(k_1,
k_2,
\ldots, k_n\)&lt;/span&gt;. The coefficient of this monomial is &lt;span
class=&quot;math inline&quot;&gt;\(+1\)&lt;/span&gt; when the sum of the cards &lt;span
class=&quot;math inline&quot;&gt;\(k_1+\cdots+k_n\)&lt;/span&gt; is even and &lt;span
class=&quot;math inline&quot;&gt;\(-1\)&lt;/span&gt; when it’s odd.&lt;/p&gt;
&lt;p&gt;Therefore, once we reduce &lt;span class=&quot;math inline&quot;&gt;\(A\)&lt;/span&gt; by
adding up all monomials of the same degree, the coefficient in front of
&lt;span class=&quot;math inline&quot;&gt;\(x^n\)&lt;/span&gt; will be the number of &lt;span
class=&quot;math inline&quot;&gt;\(n\)&lt;/span&gt;-card combinations with an even sum
minus the number of &lt;span class=&quot;math inline&quot;&gt;\(n\)&lt;/span&gt;-card
combinations with the odd sum.&lt;/p&gt;
&lt;p&gt;And the simplified form of &lt;span class=&quot;math inline&quot;&gt;\(A\)&lt;/span&gt;
is&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;math display&quot;&gt;\[
A=(1-x)^{50}(1+x)^{50}=(1-x^2)^{50} = \sum_{m=0}^{50} {50 \choose m}
(-1)^m x^{2m}.
\]&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;The fact that all terms here have even powers means that for odd
values of &lt;span class=&quot;math inline&quot;&gt;\(n\)&lt;/span&gt;, the numbers of
even-sum and odd-sum &lt;span class=&quot;math inline&quot;&gt;\(n\)&lt;/span&gt;-card
combinations are exactly equal, and so the probability to draw an even
sum is exactly 1/2. And for even values of &lt;span
class=&quot;math inline&quot;&gt;\(n=2m\)&lt;/span&gt;, the probability is greater than 1/2
when &lt;span class=&quot;math inline&quot;&gt;\((-1)^m &amp;gt; 0\)&lt;/span&gt;, i.e. when &lt;span
class=&quot;math inline&quot;&gt;\(n\)&lt;/span&gt; is divisible by 4, and less than 1/2
otherwise.&lt;/p&gt;
&lt;h2 id=&quot;bonus-calculating-the-probabilities&quot;&gt;Bonus: calculating the
probabilities&lt;/h2&gt;
&lt;p&gt;One way to calculate these probabilities is by a recursive
calculation. Here’s a Haskell function that does that.&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb1&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb1-1&quot;&gt;&lt;a href=&quot;#cb1-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;{-# LANGUAGE LambdaCase #-}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-2&quot;&gt;&lt;a href=&quot;#cb1-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Data.Ratio&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-3&quot;&gt;&lt;a href=&quot;#cb1-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Data.MemoUgly&lt;/span&gt; (memo)&lt;/span&gt;
&lt;span id=&quot;cb1-4&quot;&gt;&lt;a href=&quot;#cb1-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-5&quot;&gt;&lt;a href=&quot;#cb1-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;prob_even&lt;/span&gt;
&lt;span id=&quot;cb1-6&quot;&gt;&lt;a href=&quot;#cb1-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;  ::&lt;/span&gt; ( &lt;span class=&quot;dt&quot;&gt;Integer&lt;/span&gt; &lt;span class=&quot;co&quot;&gt;{- number of even cards -}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-7&quot;&gt;&lt;a href=&quot;#cb1-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;     , &lt;span class=&quot;dt&quot;&gt;Integer&lt;/span&gt; &lt;span class=&quot;co&quot;&gt;{- number of odd cards -}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-8&quot;&gt;&lt;a href=&quot;#cb1-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;     , &lt;span class=&quot;dt&quot;&gt;Integer&lt;/span&gt; &lt;span class=&quot;co&quot;&gt;{- number of cards to draw -}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-9&quot;&gt;&lt;a href=&quot;#cb1-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;     )&lt;/span&gt;
&lt;span id=&quot;cb1-10&quot;&gt;&lt;a href=&quot;#cb1-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Rational&lt;/span&gt; &lt;span class=&quot;co&quot;&gt;{- probability of drawing an even sum -}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-11&quot;&gt;&lt;a href=&quot;#cb1-11&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;prob_even &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; memo &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; \&lt;span class=&quot;kw&quot;&gt;case&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-12&quot;&gt;&lt;a href=&quot;#cb1-12&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  (_, _, &lt;span class=&quot;dv&quot;&gt;0&lt;/span&gt;) &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;co&quot;&gt;-- no cards to draw; the sum is 0&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-13&quot;&gt;&lt;a href=&quot;#cb1-13&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  (_, &lt;span class=&quot;dv&quot;&gt;0&lt;/span&gt;, _) &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;co&quot;&gt;-- all even cards&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-14&quot;&gt;&lt;a href=&quot;#cb1-14&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  (&lt;span class=&quot;dv&quot;&gt;0&lt;/span&gt;, _, to_draw) &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;fromInteger&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;-&lt;/span&gt; (to_draw &lt;span class=&quot;ot&quot;&gt;`mod`&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;2&lt;/span&gt;) &lt;span class=&quot;co&quot;&gt;-- all odd cards&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-15&quot;&gt;&lt;a href=&quot;#cb1-15&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  (num_even, num_odd, to_draw) &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-16&quot;&gt;&lt;a href=&quot;#cb1-16&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;kw&quot;&gt;let&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-17&quot;&gt;&lt;a href=&quot;#cb1-17&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      prob_1st_odd &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; num_odd &lt;span class=&quot;op&quot;&gt;%&lt;/span&gt; (num_even &lt;span class=&quot;op&quot;&gt;+&lt;/span&gt; num_odd)&lt;/span&gt;
&lt;span id=&quot;cb1-18&quot;&gt;&lt;a href=&quot;#cb1-18&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      if_1st_even &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; prob_even (num_even&lt;span class=&quot;op&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;, num_odd, to_draw&lt;span class=&quot;op&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;)&lt;/span&gt;
&lt;span id=&quot;cb1-19&quot;&gt;&lt;a href=&quot;#cb1-19&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      if_1st_odd &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;-&lt;/span&gt; prob_even (num_even, num_odd&lt;span class=&quot;op&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;, to_draw&lt;span class=&quot;op&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;)&lt;/span&gt;
&lt;span id=&quot;cb1-20&quot;&gt;&lt;a href=&quot;#cb1-20&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;kw&quot;&gt;in&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-21&quot;&gt;&lt;a href=&quot;#cb1-21&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      prob_1st_odd &lt;span class=&quot;op&quot;&gt;*&lt;/span&gt; if_1st_odd &lt;span class=&quot;op&quot;&gt;+&lt;/span&gt; (&lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;-&lt;/span&gt;prob_1st_odd) &lt;span class=&quot;op&quot;&gt;*&lt;/span&gt; if_1st_even&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;E.g. for &lt;span class=&quot;math inline&quot;&gt;\(n = 20\)&lt;/span&gt;, this gives&lt;/p&gt;
&lt;p&gt;&lt;span
class=&quot;math display&quot;&gt;\[p(\text{even})=\frac{26088826721}{52177653441} =
\frac{1}{2} + \frac1{104355306882}.\]&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Notice how close this is to 1/2.&lt;/p&gt;
&lt;p&gt;Alternatively, we can derive the probabilities from the proof itself.
For &lt;span class=&quot;math inline&quot;&gt;\(n =
2m\)&lt;/span&gt;, the number of even combinations minus the number of odd
combinations is &lt;span class=&quot;math inline&quot;&gt;\((-1)^m {50 \choose
m}\)&lt;/span&gt;, and their sum is the total number of &lt;span
class=&quot;math inline&quot;&gt;\(n\)&lt;/span&gt;-card combinations, &lt;span
class=&quot;math inline&quot;&gt;\(100 \choose 2m\)&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;Then the probability of drawing an even sum is&lt;/p&gt;
&lt;p&gt;&lt;span
class=&quot;math display&quot;&gt;\[p(\text{even})=\frac{\frac{1}{2}\left((-1)^m {50
\choose m} + {100 \choose 2m}\right)}{100 \choose
2m}=\frac12+(-1)^m\frac{50 \choose m}{2 {100 \choose 2m}}.\]&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;And sure enough, for &lt;span class=&quot;math inline&quot;&gt;\(n=20\)&lt;/span&gt;,&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;math display&quot;&gt;\[p(\text{even}) = \frac12+\frac{50
\choose 10}{2 {100 \choose 20}} = \frac12 +
\frac1{104355306882}.
\]&lt;/span&gt;&lt;/p&gt;
</description>
                        <pubDate>Sat, 23 Dec 2023 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2023-12-23-random-cards-puzzle</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2023-12-23-random-cards-puzzle.html</guid>
                </item>
        
                <item>
                        <title>AeroPress Go measurements. What volume do AeroPress marks correspond to?</title>
                        <description>&lt;p&gt;As a new owner of an AeroPress Go coffee brewer, I was surprised not
to be able to find (either in the manufacturer’s manual or online) what
the circle marks on the AeroPress chamber correspond to, or how much
ground coffee fits into the included scoop. So here are my own
measurements. They all assume the non-inverted brewing method with a
single standard paper filter.&lt;/p&gt;
&lt;figure&gt;
&lt;img src=&quot;/img/aeropress-go.jpg&quot; alt=&quot;AeroPress Go&quot; /&gt;
&lt;figcaption aria-hidden=&quot;true&quot;&gt;AeroPress Go&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h2 id=&quot;chamber-volume&quot;&gt;Chamber volume&lt;/h2&gt;
&lt;p&gt;For each of the three circle marks, I include three measurements: the
bottom, the middle, and the top of the circle. I measured these both
experimentally (pouring and weighing the water) and mathematically
(based on the diameter of the chamber and the height of the marks).&lt;/p&gt;
&lt;p&gt;These measurements are of the empty chamber. In reality, you will
have some coffee grounds in it, so you have to account for their volume.
(Here I assume that when you pour the water initially, it doesn’t mix
much with the grounds, and so the combined volume should be
approximately the sum of the coffee volume and the water volume. I
didn’t attempt to verify this experimentally yet.)&lt;/p&gt;
&lt;p&gt;The volume of the AeroPress Go scoop is 30 ml, so the last column in
the table below contains the adjusted volume assuming you have 30 ml of
grounds in the chamber. The numbers here are rounded to the nearest 5
ml.&lt;/p&gt;
&lt;table&gt;
&lt;tr&gt;
&lt;th&gt;
Mark
&lt;/th&gt;
&lt;th&gt;
Side
&lt;/th&gt;
&lt;th&gt;
Volume of the empty chamber (ml)
&lt;/th&gt;
&lt;th&gt;
Volume with 1 scoop (30 ml, ≈13 g) of coffee in the chamber (ml)
&lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;right&quot;&gt;
1
&lt;/td&gt;
&lt;td&gt;
low
&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;
70
&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;
40
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;right&quot;&gt;
1
&lt;/td&gt;
&lt;td&gt;
mid
&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;
85
&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;
55
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;right&quot;&gt;
1
&lt;/td&gt;
&lt;td&gt;
high
&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;
95
&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;
65
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;right&quot;&gt;
2
&lt;/td&gt;
&lt;td&gt;
low
&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;
130
&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;
100
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;right&quot;&gt;
2
&lt;/td&gt;
&lt;td&gt;
mid
&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;
140
&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;
110
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;right&quot;&gt;
2
&lt;/td&gt;
&lt;td&gt;
high
&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;
150
&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;
120
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;right&quot;&gt;
3
&lt;/td&gt;
&lt;td&gt;
low
&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;
185
&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;
155
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;right&quot;&gt;
3
&lt;/td&gt;
&lt;td&gt;
mid
&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;
200
&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;
170
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;right&quot;&gt;
3
&lt;/td&gt;
&lt;td&gt;
high
&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;
210
&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;
180
&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;h2 id=&quot;coffee-grounds-weight&quot;&gt;Coffee grounds weight&lt;/h2&gt;
&lt;p&gt;As I mentioned above, the volume of the included scoop is 30 ml. In
my measurements, I found 1 level scoop to contain around 13 g of ground
coffee, more or less independent of the grind size (which was a bit
surprising).&lt;/p&gt;
&lt;p&gt;Another number for the density of ground coffee that I found &lt;a
href=&quot;https://coffee.stackexchange.com/a/5040&quot;&gt;online&lt;/a&gt; is 0.32 g/ml,
resulting in 10 g per level scoop.&lt;/p&gt;
&lt;h2 id=&quot;brewed-coffee-yield&quot;&gt;Brewed coffee yield&lt;/h2&gt;
&lt;p&gt;How much water should you pour to get X ml of brewed coffee? I found
the output/input ratio to vary from 80% for a small portion to 90% for a
large portion, assuming 1 scoop (13 g) of ground coffee and 2 minutes of
brewing time.&lt;/p&gt;
&lt;table&gt;
&lt;tr&gt;
&lt;th&gt;
Water (ml)
&lt;/th&gt;
&lt;th&gt;
Coffee output (ml)
&lt;/th&gt;
&lt;th&gt;
Ratio (%)
&lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;right&quot;&gt;
100
&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;
80
&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;
80
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;right&quot;&gt;
140
&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;
124
&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;
89
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;right&quot;&gt;
200
&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;
182
&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;
91
&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
</description>
                        <pubDate>Sun, 23 Jul 2023 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2023-07-23-aeropress-measurements</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2023-07-23-aeropress-measurements.html</guid>
                </item>
        
                <item>
                        <title>How much current does an active bass guitar draw from a 9V battery?</title>
                        <description>&lt;p&gt;The 9V battery in my bass guitar tends to die rather often, and so I
wanted to measure how much current the bass draws.&lt;/p&gt;
&lt;p&gt;My bass is a Squier Jazz Bass with an active on-board preamp but
passive pickups (there are only two wires going to the pickups, as shown
below). Some basses have active pickups, and so their measurements may
not be comparable to mine.&lt;/p&gt;
&lt;figure&gt;
&lt;img src=&quot;/img/bass/wiring.jpeg&quot; style=&quot;max-height: 600px;&quot;&gt;
&lt;figcaption&gt;
The electronics inside my bass
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;So here are my findings.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;How much current does my active J-Bass preamp draw?&lt;/strong&gt;
Around &lt;strong&gt;11.2mA&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Does the current remain constant over time?&lt;/strong&gt; Once the
battery is connected, the current quickly drops from 11.3–11.4mA to
11.24–11.25mA and then slowly drops further to 11.21mA over a couple of
minutes. It never seems to go below 11.21mA.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Does the current increase when a string is plucked?&lt;/strong&gt;
No, it stays exactly the same regardless of whether one is playing.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Does the current depend on the potentiometer
positions?&lt;/strong&gt; No, it doesn’t depend on any of the 5 knobs: tone,
volume, pickup pan (bridge vs neck mix), or bass/treble boost.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Does the current depend on the voltage supplied by the
battery?&lt;/strong&gt; Within a reasonable range, no. I tried a few batteries
lying around (rechargeable and non-rechargeable) that happened to output
8.98V, 8.47V, and 8.31V, and the initial current consistently stayed at
11.24–11.25mA. When I plugged in a discharged battery that could only
output 6.54V, the current jumped around 6-8mA, but the bass doesn’t
sound good with such a battery.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Does it matter whether the amp is turned on?&lt;/strong&gt; Nope,
turning the amp off or even unplugging the cable from the amp does not
affect the current drawn, as long as the other end of the cable stays
plugged into the bass. Curiously, when I plugged in a bare TRS jack I
had lying around (as opposed to TS jacks normally used in instrument
cables), the current fell to 6.75mA.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Does the bass draw any current when it’s unplugged?&lt;/strong&gt;
Fortunately, it does not.&lt;/p&gt;
&lt;figure&gt;
&lt;img src=&quot;/img/bass/measurement.jpeg&quot;&gt;
&lt;figcaption&gt;
The measurement setup
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;The only other discussion of the active bass current draw I could
find is &lt;a
href=&quot;https://www.talkbass.com/threads/determining-current-draw-of-active-pickups.943898/&quot;&gt;this
TalkBass thread from 2012&lt;/a&gt;. Even though it’s about active pickups,
the author also observes the same 11mA current and complains that it’s
too high (compared to 1mA that their other bass draws).&lt;/p&gt;
&lt;p&gt;If you do similar measurements for your own bass or just happen to
know more on this subject, please let me know.&lt;/p&gt;
</description>
                        <pubDate>Sun, 14 Nov 2021 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2021-11-14-bass-guitar-current</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2021-11-14-bass-guitar-current.html</guid>
                </item>
        
                <item>
                        <title>A data structure puzzle</title>
                        <description>&lt;p&gt;Jarno Alanko offered this puzzle on twitter:&lt;/p&gt;
&lt;blockquote class=&quot;twitter-tweet&quot;&gt;
&lt;p lang=&quot;en&quot; dir=&quot;ltr&quot;&gt;
Fun but difficult data structure puzzle with an elegant solution:
Suppose we have an oracle to a permutation f on n elements. Describe a
data structure taking O(sqrt(n)) space that can compute the inverse
f^(-1)(x) for any x in O(sqrt(n)) time.
&lt;/p&gt;
— Jarno N. Alanko (&lt;span class=&quot;citation&quot;
data-cites=&quot;jnalanko&quot;&gt;@jnalanko&lt;/span&gt;)
&lt;a href=&quot;https://twitter.com/jnalanko/status/1396183583367352320?ref_src=twsrc%5Etfw&quot;&gt;May
22, 2021&lt;/a&gt;
&lt;/blockquote&gt;
&lt;p&gt;Here’s my solution. It’s a programmer’s solution: it assumes that
integers take &lt;span class=&quot;math inline&quot;&gt;\(O(1)\)&lt;/span&gt; space and hash
maps allow &lt;span class=&quot;math inline&quot;&gt;\(O(1)\)&lt;/span&gt; lookups. If you
know a solution that doesn’t make these assumptions, please let me
know!&lt;/p&gt;
&lt;p&gt;So, consider the decomposition of &lt;span
class=&quot;math inline&quot;&gt;\(f\)&lt;/span&gt; into disjoint cycles. For every cycle
that has &lt;span class=&quot;math inline&quot;&gt;\(k &amp;gt; \sqrt{n}\)&lt;/span&gt; elements,
arbitrarily pick &lt;span class=&quot;math inline&quot;&gt;\(\lceil k /
\sqrt{n}\rceil\)&lt;/span&gt; elements—“breakpoints”—such that, when moving
along the cycle, the distance between any two breakpoints is at most
&lt;span class=&quot;math inline&quot;&gt;\(\sqrt{n}\)&lt;/span&gt;. Since there are fewer
than &lt;span class=&quot;math inline&quot;&gt;\(\sqrt{n}\)&lt;/span&gt; such cycles, the
total number of breakpoints is&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;math display&quot;&gt;\[
\sum_i \lceil k_i / \sqrt{n}\rceil &amp;lt; \sum_i (k_i / \sqrt{n}+1) &amp;lt;
2\sqrt{n}.
\]&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Store all the breakpoints in a hash map &lt;span
class=&quot;math inline&quot;&gt;\(h\)&lt;/span&gt; that maps each breakpoint to the
previous breakpoint in the same cycle. Then, to invert an element &lt;span
class=&quot;math inline&quot;&gt;\(x\)&lt;/span&gt;, use the following algorithm:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;x1 := x
x2 := f(x)
while (x2 != x):
  if h contains x1:
    x1 := h(x1)
  else:
    x1 := x2
  x2 := f(x1)
return x1&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This algorithm finds the inverse element by iteratively applying
&lt;span class=&quot;math inline&quot;&gt;\(f\)&lt;/span&gt; until it comes back to &lt;span
class=&quot;math inline&quot;&gt;\(x\)&lt;/span&gt;. The hash map &lt;span
class=&quot;math inline&quot;&gt;\(h\)&lt;/span&gt; provides a shortcut to instantaneously
traverse a large part of the cycle. After less than &lt;span
class=&quot;math inline&quot;&gt;\(\sqrt{n}\)&lt;/span&gt; iterations, the loop either
finds &lt;span class=&quot;math inline&quot;&gt;\(x\)&lt;/span&gt; or finds a point &lt;span
class=&quot;math inline&quot;&gt;\(x_1\)&lt;/span&gt; for which &lt;span
class=&quot;math inline&quot;&gt;\(h(x_1)\)&lt;/span&gt; is defined. In the latter case,
&lt;span class=&quot;math inline&quot;&gt;\(x\)&lt;/span&gt; lies (cycle-wise) in the interval
&lt;span class=&quot;math inline&quot;&gt;\((h(x_1), x_1)\)&lt;/span&gt;, and once the search
is restarted from &lt;span class=&quot;math inline&quot;&gt;\(h(x_1)\)&lt;/span&gt;, it will
take less than &lt;span class=&quot;math inline&quot;&gt;\(\sqrt{n}\)&lt;/span&gt; additional
loop iterations to locate &lt;span class=&quot;math inline&quot;&gt;\(x\)&lt;/span&gt;.&lt;/p&gt;
</description>
                        <pubDate>Mon, 24 May 2021 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2021-05-24-data-structure-puzzle</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2021-05-24-data-structure-puzzle.html</guid>
                </item>
        
                <item>
                        <title>Understanding modern Linux routing (and wg-quick)</title>
                        <description>&lt;p&gt;Back in the old days, I could just type &lt;code&gt;route&lt;/code&gt; (or,
later, &lt;code&gt;ip route&lt;/code&gt;) in my Linux terminal and get an accurate
picture of all my routes. This is no longer the case.&lt;/p&gt;
&lt;p&gt;For instance, the machine where I’m writing this is connected to the
Mullvad VPN via the Wireguard protocol using the wg-quick script. I’m
pretty sure all my traffic goes through Mullvad, yet you wouldn’t be
able to tell this from my &lt;code&gt;ip route&lt;/code&gt; output:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% ip route
default via 192.168.1.1 dev enp34s0 proto static metric 100
192.168.1.0/24 dev enp34s0 proto kernel scope link src 192.168.1.121 metric 100
192.168.122.0/24 dev virbr0 proto kernel scope link src 192.168.122.1 linkdown&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Note that the default route seemingly directs all traffic through my
physical network interface, not the virtual VPN interface.&lt;/p&gt;
&lt;p&gt;So let’s figure out how this all works.&lt;/p&gt;
&lt;h2 id=&quot;routing-tables-ip-route&quot;&gt;Routing tables
(&lt;code&gt;ip route&lt;/code&gt;)&lt;/h2&gt;
&lt;p&gt;In reality, there isn’t &lt;em&gt;the&lt;/em&gt; routing table in Linux (and
hasn’t been for more than 20 years, since around Linux-2.2). Instead,
there are multiple routing tables — and a set of rules that tell the
kernel how to choose the right table for each packet.&lt;/p&gt;
&lt;p&gt;(By the way, do not confuse routing tables with iptables. To simplify
a bit, routing tables specify &lt;em&gt;how&lt;/em&gt; to deliver a packet, whereas
iptables specify &lt;em&gt;whether&lt;/em&gt; to deliver it at all. They are
completely different and unrelated.)&lt;/p&gt;
&lt;p&gt;What you see when you run &lt;code&gt;ip route&lt;/code&gt; without specifying a
table is the contents of one particular table, &lt;code&gt;main&lt;/code&gt;. Tables
are identified by integer numbers (from 1 to 2&lt;sup&gt;32&lt;/sup&gt;−1) but can
be also given textual names, which are listed in the file
&lt;code&gt;/etc/iproute2/rt_tables&lt;/code&gt;. The default one will look
something like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#
# reserved values
#
255 local
254 main
253 default
0   unspec
#
# local
#
#1  inr.ruhep&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;(Are you wondering what inr.ruhep is? This is just an example, likely
added by Alexey Kuznetsov, who worked on these parts of the Linux kernel
and iproute tools. It stands for “Institute for Nuclear Research /
Russian High Energy Physics”, the place where Alexey worked at the time,
and probably refers to their internal network. There was also an
old-school Russian computer network/ISP called &lt;a
href=&quot;http://www.radio-msu.net/about.htm&quot;&gt;RUHEP/Radio-MSU&lt;/a&gt;.)&lt;/p&gt;
&lt;p&gt;You can view the contents of any table like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% ip route list table local
% ip route list table 13&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;routing-policies-ip-rule&quot;&gt;Routing policies
(&lt;code&gt;ip rule&lt;/code&gt;)&lt;/h2&gt;
&lt;p&gt;So how does the kernel know which routing table to apply? It uses the
“routing policy database”, which is managed by the &lt;code&gt;ip rule&lt;/code&gt;
command. In particular, &lt;code&gt;ip rule&lt;/code&gt; without any arguments will
print all existing rules. These are mine:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% ip rule
0:  from all lookup local
32764:  from all lookup main suppress_prefixlength 0
32765:  not from all fwmark 0xca6c lookup 51820
32766:  from all lookup main
32767:  from all lookup default&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The numbers you see on the left (0, 32764, …) are rule priorities:
the lower the priority, the higher the priority. That is to say, rules
with lower numbers are processed first.&lt;/p&gt;
&lt;p&gt;Apart from the priority, each rule has also a &lt;em&gt;selector&lt;/em&gt; and
an &lt;em&gt;action&lt;/em&gt;. The selector tells us whether the rule applies to
the packet at hand. If it does, the action is executed. The most common
action is to consult a particular routing table (see the previous
section). If that routing table contained a route for our packet, then
we’re done; otherwise, we proceed to the next rule.&lt;/p&gt;
&lt;p&gt;The rules with priorities 0, 32766 and 32767 above are created
automatically by the kernel. To quote the &lt;code&gt;ip-rule(8)&lt;/code&gt; man
page:&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;&lt;p&gt;Priority: 0, Selector: match anything, Action: lookup routing
table local (ID 255). The local table is a special routing table
containing high priority control routes for local and broadcast
addresses.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Priority: 32766, Selector: match anything, Action: lookup routing
table main (ID 254). The main table is the normal routing table
containing all non-policy routes. This rule may be deleted and/or
overrid‐ den with other ones by the administrator.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Priority: 32767, Selector: match anything, Action: lookup routing
table default (ID 253). The default table is empty. It is reserved for
some post-processing if no previous default rules selected the packet.
This rule may also be deleted.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The other two rules have been created by the wg-quick script. If you
want to understand how they work, read on.&lt;/p&gt;
&lt;h2 id=&quot;understanding-wg-quick&quot;&gt;Understanding wg-quick&lt;/h2&gt;
&lt;p&gt;Let’s look at the two rules that are added by wg-quick:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;32764:  from all lookup main suppress_prefixlength 0
32765:  not from all fwmark 0xca6c lookup 51820&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;At first sight, these are quite cryptic: what does
&lt;code&gt;suppress_prefixlength&lt;/code&gt; do, what is 0xca6c, and how can a
packet be “not from all”?&lt;/p&gt;
&lt;h3 id=&quot;rule-32764&quot;&gt;Rule 32764&lt;/h3&gt;
&lt;p&gt;Let’s start from the 32764 rule: as it has a lower number, it’s
considered first.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;32764:  from all lookup main suppress_prefixlength 0&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The rule has no selector, making the kernel consult the
&lt;code&gt;main&lt;/code&gt; table for every single packet.&lt;/p&gt;
&lt;p&gt;If this was the whole rule, every packet would be routed by the main
table, never reaching the VPN. This is why the action also contains a
&lt;em&gt;suppressor&lt;/em&gt;: &lt;code&gt;suppress_prefixlength 0&lt;/code&gt;. From the
&lt;code&gt;ip-rule(8)&lt;/code&gt; man page&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;suppress_prefixlength NUMBER
    reject routing decisions that have a prefix length of NUMBER or less.&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here “prefix” refers to the address or range of addresses matched in
the routing table. So if you have a route for 10.2.3.4, its prefix
length is 32 (bits); if you change it to 10.0.0.0/8, the prefix length
will be 8.&lt;/p&gt;
&lt;p&gt;What is a prefix of length 0 or less? It’s the empty prefix,
0.0.0.0/0, corresponding to the default route. So if the packet was
routed by the default route from &lt;code&gt;main&lt;/code&gt;, that routing
decision is ignored; otherwise, it’s respected.&lt;/p&gt;
&lt;p&gt;To summarize, the effect of this rule is to respect all manual routes
that the administrator might have added to the &lt;code&gt;main&lt;/code&gt; table.
However, if the packet didn’t match any of the specific routes, then
instead of applying the default route, we’re proceeding to the next
rule.&lt;/p&gt;
&lt;h3 id=&quot;rule-32765&quot;&gt;Rule 32765&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;32765:  not from all fwmark 0xca6c lookup 51820&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The “not from all” bit is just a quirk of how &lt;code&gt;ip rule&lt;/code&gt;
formats its rules. A better way to express it would be&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;32765:  from all not fwmark 0xca6c lookup 51820&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It’s just that when no “from” prefix (address or range) is present in
the rule’s selector, &lt;code&gt;ip rule&lt;/code&gt; prints “from all”.&lt;/p&gt;
&lt;p&gt;51820 is a routing table, also created by wg-quick, containing a
single role:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% ip route list table 51820
default dev mullvad scope link&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So the effect of the rule is to route everything that reached it
through the VPN, with one exception: the mysterious
&lt;code&gt;not fwmark 0xca6c&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;0xca6c is just a numerical label (“firewall mark”) that wg-quick
asked wg to mark all of the packets that it emits. These are packets
that already encapsulate other packets and are targeted to your VPN
peer/server. If these packages were routed back to wireguard, that would
create an infinite loop of wrappers on top of wrappers.&lt;/p&gt;
&lt;p&gt;So the selector ensures that packets that have already been
encapsulated can escape through your normal internet connection. Since
these packets are ignored by this rule, they proceed to the rule&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;32766:  from all lookup main&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;But now there is no suppressor, so these packages are free to use the
default route.&lt;/p&gt;
&lt;p&gt;Fun fact: wg-quick uses the same numbers for the table and the
fwmark: 0xca6c is just 51820 in hexadecimal.&lt;/p&gt;
&lt;p&gt;Overall, this setup works quite well. Older VPN scripts used to
override your default route in the main table when connecting to the VPN
and restore it when disconnecting. Sometimes this wouldn’t work, and
after disconnecting from the VPN you would be left without any default
route at all. wg-quick doesn’t have this problem, as it never messes
with your &lt;code&gt;main&lt;/code&gt; routing table. All it has to do when
disconnecting is delete its two rules, and your default route is active
again, Or you could even do that yourself with
&lt;code&gt;ip rule del&lt;/code&gt;.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;Félix Baylac Jacqué says:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;If you want to go further on advanced linux-based routing:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;man ip-vrf&lt;/code&gt; &amp;lt;= routing tables attached to a
particular netdev.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;man ip-netns&lt;/code&gt; &amp;lt;= network namespaces. There’s a nice
trick using them to prevent any packet leakeage w/ wireguard &lt;a
href=&quot;https://www.wireguard.com/netns/&quot;
class=&quot;uri&quot;&gt;https://www.wireguard.com/netns/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
</description>
                        <pubDate>Sat, 27 Feb 2021 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2021-02-27-linux-routing</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2021-02-27-linux-routing.html</guid>
                </item>
        
                <item>
                        <title>My podcast editing workflow in REAPER</title>
                        <description>&lt;p&gt;I divide podcast post-production into two parts:&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;Editing: cutting and moving the audio around. This includes reducing
pauses (or sometimes adding them), removing parts that didn’t turn out
interesting, and cutting out some excessive filler sounds. The goal here
is to make the conversation concise, engaging, and easy to listen
to.&lt;/li&gt;
&lt;li&gt;Mixing: figuring out which plugins/effects to apply so that the
resulting audio &lt;em&gt;sounds&lt;/em&gt; good.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;This is not to say that editing and mixing happens in this strict
order; on the contrary, while editing, I notice things that could be
improved and adjust the plugin chains accordingly. But it’s useful to
distinguish these two concepts.&lt;/p&gt;
&lt;p&gt;Here is my podcast &lt;em&gt;editing&lt;/em&gt; check-list for REAPER, which I’ll
elaborate on below:&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;Create the project; import and align the tracks&lt;/li&gt;
&lt;li&gt;Normalize each track to 0dB and adjust their gain&lt;/li&gt;
&lt;li&gt;Apply dynamic split/noise gate to each track&lt;/li&gt;
&lt;li&gt;Edit at item boundaries&lt;/li&gt;
&lt;li&gt;Re-listen and make final edits&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;create-the-project-import-and-align-the-tracks&quot;&gt;Create the
project; import and align the tracks&lt;/h2&gt;
&lt;p&gt;To create a project, it’s convenient to use a template that contains
a standard set of tracks (including the intro/outro music) and effects.
Here is what mine looks like:&lt;/p&gt;
&lt;figure&gt;
&lt;img src=&quot;/img/podcast-editing-in-reaper/template.png&quot; width=&quot;800&quot;
alt=&quot;An empty project template&quot; /&gt;
&lt;figcaption aria-hidden=&quot;true&quot;&gt;An empty project template&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h2 id=&quot;normalize&quot;&gt;Normalize&lt;/h2&gt;
&lt;p&gt;When recording, I set the gain very conservatively to prevent
clipping. As a result, an individual raw track may peak at as low as
-15dB. So the first thing I do is normalize each track to peak at 0dB.
This has little to do with the final volume of the track (which will be
controlled by the volume faders/knobs), but normalizing tracks achieves
a few nice things:&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;It makes the waveform easier to read.&lt;/li&gt;
&lt;li&gt;When setting up the compressor and other plugins, it makes the
threshold a more sane and standard level (e.g. -25dB instead of
-40dB).&lt;/li&gt;
&lt;li&gt;By default, volume faders in reaper go up to +20dB, so if raw track
peaks at -15dB, the fader may not have enough gain to bring the audio to
the right level.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;dynamic-split&quot;&gt;Dynamic split&lt;/h2&gt;
&lt;figure&gt;
&lt;img src=&quot;/img/podcast-editing-in-reaper/before_dyn_split.png&quot;
alt=&quot;Before dynamic split&quot; /&gt;
&lt;figcaption aria-hidden=&quot;true&quot;&gt;Before dynamic split&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
&lt;img src=&quot;/img/podcast-editing-in-reaper/after_dyn_split.png&quot;
alt=&quot;After dynamic split&quot; /&gt;
&lt;figcaption aria-hidden=&quot;true&quot;&gt;After dynamic split&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;The dynamic split (or more precisely, the way I use it) acts like a
noise gate; that is, its main goal is to silence the parts where the
person is not talking. However, it has two big advantages over simply
applying a noise gate effect:&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;I can visually see which parts are silenced, and adjust them by
dragging the item edges.&lt;/li&gt;
&lt;li&gt;I can easily move the non-silent parts around — whether I need to
rearrange parts of the conversation or just fine-tune the pause between
different speakers.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Here are my typical settings for the dynamic split.&lt;/p&gt;
&lt;figure&gt;
&lt;img src=&quot;/img/podcast-editing-in-reaper/dyn_split_dialog.png&quot;
width=&quot;400&quot; alt=&quot;Dynamic split dialog with my typical settings&quot; /&gt;
&lt;figcaption aria-hidden=&quot;true&quot;&gt;Dynamic split dialog with my typical
settings&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;There are some obvious settings like min slice and silence lengths
and the threshold/hysteresis; and then there are somewhat less obvious
settings that are worth paying attention to.&lt;/p&gt;
&lt;p&gt;Leading and trailing pads are simply extra bits of sound that are
left untouched even after the audio goes under the threshold (trailing
pad) or before it emerges from below the threshold (leading pad).
Without the pads, I would either have to set the threshold too
conservatively, or manually adjust all the items, un-silencing the parts
where a person starts or finishes talking.&lt;/p&gt;
&lt;p&gt;You’ll also notice that I left the ‘Fade pad’ box unchecked. This is
because a fade would span the whole pad, and a 300ms or even a 70ms fade
is too large.&lt;/p&gt;
&lt;p&gt;However, I do want the fades to smooth the edges of the items. So
after a dynamic split, I select all the items, go to Item Properties,
and manually set the fades to 0.03 (i.e. 30ms). This affects all the
selected items.&lt;/p&gt;
&lt;figure&gt;
&lt;img src=&quot;/img/podcast-editing-in-reaper/fades.png&quot; width=&quot;400&quot;
alt=&quot;Applying fades to split items&quot; /&gt;
&lt;figcaption aria-hidden=&quot;true&quot;&gt;Applying fades to split
items&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;&lt;strong&gt;Tip:&lt;/strong&gt; make sure to unselect the items after this. If
you start editing (e.g. resizing) items, all selected items will be
affected, creating a big mess.&lt;/p&gt;
&lt;h2 id=&quot;edit-at-item-boundaries&quot;&gt;Edit at item boundaries&lt;/h2&gt;
&lt;p&gt;At this stage I just go through all the places where one person stops
and another starts talking. These are the places that require the most
editing, so I like to take care of them first, without having to listen
to the whole recording.&lt;/p&gt;
&lt;h2 id=&quot;re-listen-and-make-final-edits&quot;&gt;Re-listen and make final
edits&lt;/h2&gt;
&lt;p&gt;At this point, I listen to the full length episode, and make the
final edits as needed. Sometimes I do this in REAPER, but mostly I like
to render the episode and take it for a walk, writing down the
timestamps where an edit is needed.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Tip:&lt;/strong&gt; when applying edits according to a list of
timestamps, move through them in the direction from the end towards the
beginning of the episode. Otherwise, earlier edits will affect the
timestamps that occur later in the episode.&lt;/p&gt;
</description>
                        <pubDate>Sun, 21 Feb 2021 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2021-02-21-podcast-editing-in-reaper</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2021-02-21-podcast-editing-in-reaper.html</guid>
                </item>
        
                <item>
                        <title>StateT vs. IORef: a benchmark</title>
                        <description>&lt;p&gt;Sometimes I’m writing an IO loop in Haskell, and I need some sort of
a counter or accumulator. The two main options are to use a mutable
reference (IORef) or to put a StateT transformer on top the IO
monad.&lt;/p&gt;
&lt;p&gt;I was curious, though, if there was a difference in efficiency
between these two approaches. Intuitively, IORefs are dedicated heap
objects, while a StateT transformer’s state becomes “just” a local
variable, so StateT might optimize better. But how much of a difference
does it make?&lt;/p&gt;
&lt;p&gt;So I benchmarked the four functions, all of which calculate the sum
of numbers between 1 and &lt;code&gt;n = 1000&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;base_sum&lt;/code&gt; simply calls &lt;code&gt;sum&lt;/code&gt; from the base
package; &lt;code&gt;state_sum&lt;/code&gt; and &lt;code&gt;stateT_sum&lt;/code&gt; maintain the
accumulator using the &lt;code&gt;State Int&lt;/code&gt; and
&lt;code&gt;StateT Int IO&lt;/code&gt; monads, respectively, and
&lt;code&gt;ioref_sum&lt;/code&gt; uses an &lt;code&gt;IORef&lt;/code&gt; within the
&lt;code&gt;IO&lt;/code&gt; monad. And here are the results, as reported by
criterion.&lt;/p&gt;
&lt;figure&gt;
&lt;img src=&quot;/img/StateT-vs-IORef.svg&quot;
alt=&quot;Mean execution times reported by criterion. The error bars are the lower and upper bounds of the mean as reported by criterion, which I think are 95% bootstrap confidence intervals.&quot; /&gt;
&lt;figcaption aria-hidden=&quot;true&quot;&gt;Mean execution times reported by
criterion. The error bars are the lower and upper bounds of the mean as
reported by criterion, which I think are 95% bootstrap confidence
intervals.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;I’m not sure how &lt;code&gt;stateT_sum&lt;/code&gt; manages to be faster than
&lt;code&gt;state_sum&lt;/code&gt; and &lt;code&gt;base_sum&lt;/code&gt; (this doesn’t appear to
be a statistical fluke), but what’s clear is that &lt;code&gt;ioref_sum&lt;/code&gt;
is significantly slower of them all.&lt;/p&gt;
&lt;p&gt;So if 3ns per state access matter to you, go for &lt;code&gt;StateT&lt;/code&gt;
even when you are in &lt;code&gt;IO&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;(Update: also check out the &lt;a
href=&quot;https://old.reddit.com/r/haskell/comments/knne96/statet_vs_ioref_a_benchmark/&quot;&gt;comments
on reddit&lt;/a&gt;, especially the ones by u/VincentPepper.)&lt;/p&gt;
&lt;p&gt;Here’s the full benchmark code. It was compiled with &lt;code&gt;-O2&lt;/code&gt;
by GHC 8.8.4 and run on AMD Ryzen 7 3700X.&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb1&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb1-1&quot;&gt;&lt;a href=&quot;#cb1-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Criterion&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-2&quot;&gt;&lt;a href=&quot;#cb1-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Criterion.Main&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-3&quot;&gt;&lt;a href=&quot;#cb1-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-4&quot;&gt;&lt;a href=&quot;#cb1-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Control.Monad.State&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-5&quot;&gt;&lt;a href=&quot;#cb1-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Data.IORef&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-6&quot;&gt;&lt;a href=&quot;#cb1-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-7&quot;&gt;&lt;a href=&quot;#cb1-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;base_sum ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Int&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Int&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-8&quot;&gt;&lt;a href=&quot;#cb1-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;base_sum n &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;sum&lt;/span&gt; [&lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;..&lt;/span&gt; n]&lt;/span&gt;
&lt;span id=&quot;cb1-9&quot;&gt;&lt;a href=&quot;#cb1-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-10&quot;&gt;&lt;a href=&quot;#cb1-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;state_sum ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Int&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Int&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-11&quot;&gt;&lt;a href=&quot;#cb1-11&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;state_sum n &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;flip&lt;/span&gt; execState &lt;span class=&quot;dv&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-12&quot;&gt;&lt;a href=&quot;#cb1-12&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  forM_ [&lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;..&lt;/span&gt;n] &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; \i &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-13&quot;&gt;&lt;a href=&quot;#cb1-13&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    modify&amp;#39; (&lt;span class=&quot;op&quot;&gt;+&lt;/span&gt;i)&lt;/span&gt;
&lt;span id=&quot;cb1-14&quot;&gt;&lt;a href=&quot;#cb1-14&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-15&quot;&gt;&lt;a href=&quot;#cb1-15&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;stateT_sum ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Int&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;IO&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Int&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-16&quot;&gt;&lt;a href=&quot;#cb1-16&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;stateT_sum n &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;flip&lt;/span&gt; execStateT &lt;span class=&quot;dv&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-17&quot;&gt;&lt;a href=&quot;#cb1-17&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  forM_ [&lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;..&lt;/span&gt;n] &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; \i &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-18&quot;&gt;&lt;a href=&quot;#cb1-18&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    modify&amp;#39; (&lt;span class=&quot;op&quot;&gt;+&lt;/span&gt;i)&lt;/span&gt;
&lt;span id=&quot;cb1-19&quot;&gt;&lt;a href=&quot;#cb1-19&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-20&quot;&gt;&lt;a href=&quot;#cb1-20&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;ioref_sum ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Int&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;IO&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Int&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-21&quot;&gt;&lt;a href=&quot;#cb1-21&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;ioref_sum n &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-22&quot;&gt;&lt;a href=&quot;#cb1-22&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  ref &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; newIORef &lt;span class=&quot;dv&quot;&gt;0&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-23&quot;&gt;&lt;a href=&quot;#cb1-23&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  forM_ [&lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;..&lt;/span&gt;n] &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; \i &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-24&quot;&gt;&lt;a href=&quot;#cb1-24&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    modifyIORef&amp;#39; ref (&lt;span class=&quot;op&quot;&gt;+&lt;/span&gt;i)&lt;/span&gt;
&lt;span id=&quot;cb1-25&quot;&gt;&lt;a href=&quot;#cb1-25&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  readIORef ref&lt;/span&gt;
&lt;span id=&quot;cb1-26&quot;&gt;&lt;a href=&quot;#cb1-26&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-27&quot;&gt;&lt;a href=&quot;#cb1-27&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;main &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-28&quot;&gt;&lt;a href=&quot;#cb1-28&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;let&lt;/span&gt; n &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;1000&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-29&quot;&gt;&lt;a href=&quot;#cb1-29&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  defaultMain&lt;/span&gt;
&lt;span id=&quot;cb1-30&quot;&gt;&lt;a href=&quot;#cb1-30&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    [ bench &lt;span class=&quot;st&quot;&gt;&amp;quot;base_sum&amp;quot;&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; whnf base_sum n&lt;/span&gt;
&lt;span id=&quot;cb1-31&quot;&gt;&lt;a href=&quot;#cb1-31&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    , bench &lt;span class=&quot;st&quot;&gt;&amp;quot;state_sum&amp;quot;&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; whnf state_sum n&lt;/span&gt;
&lt;span id=&quot;cb1-32&quot;&gt;&lt;a href=&quot;#cb1-32&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    , bench &lt;span class=&quot;st&quot;&gt;&amp;quot;stateT_sum&amp;quot;&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; whnfAppIO stateT_sum n&lt;/span&gt;
&lt;span id=&quot;cb1-33&quot;&gt;&lt;a href=&quot;#cb1-33&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    , bench &lt;span class=&quot;st&quot;&gt;&amp;quot;ioref_sum&amp;quot;&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; whnfAppIO ioref_sum n&lt;/span&gt;
&lt;span id=&quot;cb1-34&quot;&gt;&lt;a href=&quot;#cb1-34&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    ]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
</description>
                        <pubDate>Tue, 29 Dec 2020 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2020-12-29-statet-vs-ioref</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2020-12-29-statet-vs-ioref.html</guid>
                </item>
        
                <item>
                        <title>Laptop vs. desktop for compiling Haskell code</title>
                        <description>&lt;p&gt;I’ve been using various laptops as daily drivers for the last 12
years, and I’ve never felt they were inadequate — until this year. There
were a few things that made me put together a desktop PC last month, but
a big reason was to improve my Haskell compilation experience on big
projects.&lt;/p&gt;
&lt;p&gt;So let’s test how fast Haskell code compiles on a laptop vs. a
desktop.&lt;/p&gt;
&lt;h2 id=&quot;specs&quot;&gt;Specs&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th style=&quot;text-align: right;&quot;&gt;Laptop&lt;/th&gt;
&lt;th style=&quot;text-align: right;&quot;&gt;Desktop&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;CPU&lt;/td&gt;
&lt;td style=&quot;text-align: right;&quot;&gt;Intel Core i7-6500U&lt;/td&gt;
&lt;td style=&quot;text-align: right;&quot;&gt;AMD Ryzen 7 3700X&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Base clock&lt;/td&gt;
&lt;td style=&quot;text-align: right;&quot;&gt;2.5 GHz&lt;/td&gt;
&lt;td style=&quot;text-align: right;&quot;&gt;3.6 GHz&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Boost clock&lt;/td&gt;
&lt;td style=&quot;text-align: right;&quot;&gt;3.1 GHz&lt;/td&gt;
&lt;td style=&quot;text-align: right;&quot;&gt;4.4 GHz&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Number of cores&lt;/td&gt;
&lt;td style=&quot;text-align: right;&quot;&gt;2&lt;/td&gt;
&lt;td style=&quot;text-align: right;&quot;&gt;8&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Memory speed&lt;/td&gt;
&lt;td style=&quot;text-align: right;&quot;&gt;2133 MT/s&lt;/td&gt;
&lt;td style=&quot;text-align: right;&quot;&gt;4000 MT/s&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id=&quot;methodology&quot;&gt;Methodology&lt;/h2&gt;
&lt;p&gt;I picked four Haskell packages for this test: pandoc, lens, hledger,
and criterion. An individual test consists of building one of these
packages or all of them together (represented here by a meta-package
called &lt;code&gt;all&lt;/code&gt;).&lt;/p&gt;
&lt;p&gt;The build time includes the time to build all of the transitive
dependencies. All sources are pre-downloaded, so just the compilation is
timed.&lt;/p&gt;
&lt;p&gt;The compilation is done using stack (current master with &lt;a
href=&quot;https://github.com/commercialhaskell/stack/issues/5435#issuecomment-749036479&quot;&gt;a
custom patch&lt;/a&gt;), GHC 8.8.4, and the lts-16.26 Stackage snapshot, with
the default flags.&lt;/p&gt;
&lt;p&gt;The build time of each package (including the &lt;code&gt;all&lt;/code&gt;
meta-package) is measured 3 times, with all tests happening in a random
order. There is a 2 minute break after each build to let the CPU cool
down.&lt;/p&gt;
&lt;p&gt;The CPU frequency governor is set to &lt;code&gt;performance&lt;/code&gt; while
compiling and to &lt;code&gt;powersave&lt;/code&gt; during the cooling breaks.&lt;/p&gt;
&lt;p&gt;To calculate the average level of parallelism achieved on each
package, I divide the user CPU time by the wall-clock time (as reported
by GNU time’s &lt;code&gt;%U&lt;/code&gt; and &lt;code&gt;%e&lt;/code&gt;, respectively), using
the data from the desktop benchmark (as it has more potential for
parallelism).&lt;/p&gt;
&lt;p&gt;The full benchmark script is available &lt;a
href=&quot;/files/2020-12-22-haskell-compilation-laptop-desktop/benchmark-compilation-time.sh&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I also measured the average power drawn by both computers, both when
running the benchmark and in the idle state. As my power meter only
reports the instantaneous power and cumulative energy, I measured the
cumulative energy (in W⋅h) at several random time points and fitted an
ordinary least squares linear regression to find the average power.&lt;/p&gt;
&lt;h2 id=&quot;results&quot;&gt;Results&lt;/h2&gt;
&lt;p&gt;The first result is that I had to take the laptop outside the house
(0°C) to even be able to finish this benchmark; otherwise the computer
would overheat and shut down. While the laptop was outside, the CPU
temperature would rise up to 74°C. The desktop, on the other hand, had
no issue keeping itself cool (&amp;lt; 60°C) under the room temperature with
only the stock coolers.&lt;/p&gt;
&lt;p&gt;And here are the timings.&lt;/p&gt;
&lt;!-- html table generated in R 4.0.3 by xtable 1.8-4 package --&gt;
&lt;!-- Tue Dec 22 17:50:44 2020 --&gt;
&lt;table&gt;
&lt;caption align=&quot;bottom&quot;&gt;
Mean compile times (minutes:seconds) and their ratio
&lt;/caption&gt;
&lt;tr&gt;
&lt;th&gt;
package
&lt;/th&gt;
&lt;th&gt;
desktop
&lt;/th&gt;
&lt;th&gt;
laptop
&lt;/th&gt;
&lt;th&gt;
ratio
&lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
lens
&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;
01:50
&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;
02:53
&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;
1.57
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
criterion
&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;
03:49
&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;
06:05
&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;
1.59
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
hledger
&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;
04:28
&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;
07:51
&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;
1.75
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
pandoc
&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;
14:07
&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;
22:30
&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;
1.59
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
all
&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;
15:20
&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;
26:48
&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;
1.75
&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;figure&gt;
&lt;img src=&quot;/img/haskell-compilation-laptop-desktop/timings.svg&quot;
alt=&quot;The column height represents the mean time, and the error bars (which collapse into thick black lines) show the maximum and minimum of the 3 runs&quot; /&gt;
&lt;figcaption aria-hidden=&quot;true&quot;&gt;The column height represents the mean
time, and the error bars (which collapse into thick black lines) show
the maximum and minimum of the 3 runs&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;We can also see how well the desktop/laptop speed ratio is predicted
by the parallelism achieved for each package.&lt;/p&gt;
&lt;p&gt;&lt;img
src=&quot;/img/haskell-compilation-laptop-desktop/timings-vs-parallelism.svg&quot; /&gt;&lt;/p&gt;
&lt;p&gt;The average power (where averaging also includes the cooling breaks)
drawn during the benchmark was 19W for the laptop and 65W for the
desktop.&lt;/p&gt;
&lt;p&gt;The average idle power was 3W for the laptop and 37W for the
desktop.&lt;/p&gt;
&lt;h2 id=&quot;conclusions&quot;&gt;Conclusions&lt;/h2&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;&lt;p&gt;The overheating laptop issue is real and has happened to me
numerous times while working on real projects, forcing me to limit the
number of threads and making the compilation even slower. This alone was
worth getting a desktop PC.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;There’s a decent increase in the compilation speed, but it’s not
huge. The average time ratio (1.65) is much closer to the ratio of clock
frequencies (1.42–1.44) than to the difference in the combined power of
all cores. Also, the laptop/desktop ratio grows slowly with the level of
parallelism. My interpretation of this is that the (dual-core, 4
threads) laptop is capable of exploiting most of the parallelism
available when building these packages.&lt;/p&gt;
&lt;p&gt;So the way things are today, I’d say a quad-core or probably even a
dual-core CPU is enough for a Haskell developer to compile code.&lt;/p&gt;
&lt;p&gt;That said, I hope that our build systems become better at parallelism
over the coming years.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;In terms of power efficiency, the laptop is a clear winner: twice
as power-efficient for compilation (after adjusting for the speed
difference) and 13 times as power-efficient when idle.
&lt;!-- NB: the ratios were computed using more precision than reported above,
hence the results may appear wrong, but they aren&apos;t --&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;I also played a bit with overclocking the desktop’s CPU. I’m not
an experienced overclocker and didn’t dare to go to the extreme
settings, but moderate overclocking (raising the clock speed to 3.8 GHz
or enabling MSI Game Boost) actually resulted in longer compile times.
My understanding is that overclocking affects all cores, while CPU’s
default “boosting” logic (which is disabled by overclocking) can
significantly boost the clock frequency of one or two cores when needed.
The latter seems to be a much better fit for a compilation workload,
where most of the cores are idle most of the time.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;acknowledgments&quot;&gt;Acknowledgments&lt;/h2&gt;
&lt;p&gt;Thanks to Félix Baylac-Jacqué for educating me about the modern PC
parts.&lt;/p&gt;
</description>
                        <pubDate>Tue, 22 Dec 2020 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2020-12-22-haskell-compilation-laptop-desktop</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2020-12-22-haskell-compilation-laptop-desktop.html</guid>
                </item>
        
                <item>
                        <title>system2 in R considered inadequate</title>
                        <description>&lt;p&gt;When you need to run another program (executable) from your program,
there are two different ways to go about it: to run the executable
directly, or to go through the shell.&lt;/p&gt;
&lt;p&gt;“Going through the shell” means that instead of running the
executable you want to run, your program will run the shell,
&lt;code&gt;/bin/sh&lt;/code&gt;, which in turn will be told (via the
&lt;code&gt;-c&lt;/code&gt; option) to run the executable you want.&lt;/p&gt;
&lt;p&gt;Why would one want to go through the shell? There are a couple of
advantages:&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;When going through the shell, you can use a familiar syntax to write
the arguments, e.g. &lt;code&gt;system(&quot;cp -r dir1 dir2&quot;)&lt;/code&gt;. On the other
hand, when running the executable directly, you have to split the
command into the executable name (&lt;code&gt;cp&lt;/code&gt;) and the array of
arguments &lt;code&gt;&quot;-r&quot;, &quot;dir1&quot;, &quot;dir2&quot;&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;You get for free the various shell features: input/output
redirection, pipes, variable expansions etc.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;But there are downsides, too:&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;&lt;p&gt;There is a bit of overhead for launching the shell and having the
shell parse the command and do other housekeeping. Often this overhead
is negligible compared to all the other stuff that your program is
doing, but of course it depends on what exactly it’s doing and how many
times it has to run the shell/executable.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;More importantly, now you have to worry about how exactly the
shell will parse your command. If &lt;code&gt;dir1&lt;/code&gt; and
&lt;code&gt;dir2&lt;/code&gt; are variables, you might construct your shell command
as&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;paste(&amp;quot;cp -r&amp;quot;, dir1, dir2)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;(R’s &lt;code&gt;paste()&lt;/code&gt; function will by default add spaces between
its arguments.)&lt;/p&gt;
&lt;p&gt;But what if &lt;code&gt;dir1&lt;/code&gt; or &lt;code&gt;dir2&lt;/code&gt; contain spaces or
other special shell characters?&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;For these reasons, my rule of thumb is to always run the executable
directly, unless there’s a specific reason why a shell is needed, which
in my experience is very rare.&lt;/p&gt;
&lt;p&gt;Most programming languages offer both options:&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;&lt;p&gt;The C standard defines the &lt;code&gt;system&lt;/code&gt; function, which
executes a command through the &lt;em&gt;command processor&lt;/em&gt; (i.e. the
shell on POSIX systems). On POSIX systems, one can instead execute the
command directly by using &lt;code&gt;fork&lt;/code&gt; and &lt;code&gt;execvp&lt;/code&gt; (or
another function from the &lt;code&gt;exec*&lt;/code&gt; family).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;In Python, there’s a boolean &lt;code&gt;shell&lt;/code&gt; parameter to the
&lt;code&gt;subprocess.run()&lt;/code&gt; function that specifies whether the call
should go through the shell.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;In Haskell’s &lt;code&gt;System.Process&lt;/code&gt;, there’s
&lt;code&gt;callCommand&lt;/code&gt;, which goes through the shell, and there’s
&lt;code&gt;callProcess&lt;/code&gt;, which doesn’t.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;In Perl, there’s just one function, &lt;code&gt;system&lt;/code&gt;, which
does both things depending on how it’s invoked. If it gets more than one
argument, it runs the executable directly, treating the first argument
as the executable name and the rest as arguments for the executable.&lt;/p&gt;
&lt;p&gt;If there’s just one argument to &lt;code&gt;system&lt;/code&gt;, then it’s
considered as a shell command.&lt;/p&gt;
&lt;p&gt;This is still less explicit than I prefer (what if you need to run an
executable without arguments, but the executable name may contains
spaces or special characters?), but it’s at least something.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Now on to R. In R, there are two functions, &lt;code&gt;system&lt;/code&gt; and
&lt;code&gt;system2&lt;/code&gt;. &lt;code&gt;system&lt;/code&gt; takes the command as a single
string, so it makes sense that it would go through the shell.
&lt;code&gt;system2&lt;/code&gt; is described as “a more portable and flexible
interface than ‘system’”, and it takes the command and the list of
arguments as separate arguments:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;   system2(command, args, ...)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So one might hope that it doesn’t go through the shell. Sadly, not
only does it goes through the shell, it doesn’t even attempt to quote
the args list so that it corresponds to the arguments actually received
by the command. A single argument in &lt;code&gt;args&lt;/code&gt; may end up as
several arguments to &lt;code&gt;command&lt;/code&gt; — or even vice versa!&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt; system2(&amp;quot;printf&amp;quot;, c(&amp;quot;%s\\\\n&amp;quot; , &amp;quot;a b&amp;quot;))
a
b
&amp;gt; system2(&amp;quot;printf&amp;quot;, c(&amp;quot;%s\\\\n&amp;quot; , &amp;quot;&amp;#39;&amp;quot;, &amp;quot;a&amp;quot;, &amp;quot;b&amp;quot;, &amp;quot;&amp;#39;&amp;quot;))
 a b &lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Looking at the source code for &lt;code&gt;system2&lt;/code&gt;, the argument
list is simply concatenated with spaces — what’s the point of having it
as a list at all?&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;system2 &amp;lt;- function(command, args = character(), ...) {
    ...
    command &amp;lt;- paste(c(env, shQuote(command), args), collapse = &amp;quot; &amp;quot;)
    ...
    .Internal(system(command, intern, timeout))
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As far as I can tell, there’s currently no standard way in R to run
an executable directly, bypassing the shell, which is a shame. In order
to avoid issues with spaces and special characters in arguments, you
have to quote each one using &lt;code&gt;shQuote&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt; system2(&amp;quot;printf&amp;quot;, c(&amp;quot;%s\\\\n&amp;quot; , shQuote(&amp;quot;a b&amp;quot;)))
a b&lt;/code&gt;&lt;/pre&gt;
</description>
                        <pubDate>Fri, 11 Dec 2020 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2020-12-11-r-system2</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2020-12-11-r-system2.html</guid>
                </item>
        
                <item>
                        <title>Sort directories by the newest file</title>
                        <description>&lt;p&gt;If you need to clean up a file system (especially your $HOME
directory from some ancient dot-files), it may be useful to sort the
top-level directories by the last modified time of any file inside
them.&lt;/p&gt;
&lt;p&gt;Here’s the command I came up with:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb1&quot;&gt;&lt;pre class=&quot;sourceCode sh&quot;&gt;&lt;code class=&quot;sourceCode bash&quot;&gt;&lt;span id=&quot;cb1-1&quot;&gt;&lt;a href=&quot;#cb1-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;fu&quot;&gt;find&lt;/span&gt; &lt;span class=&quot;at&quot;&gt;-printf&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;#39;%T@/%P\n&amp;#39;&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;awk&lt;/span&gt; &lt;span class=&quot;at&quot;&gt;-F&lt;/span&gt;/ &lt;span class=&quot;dt&quot;&gt;\&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-2&quot;&gt;&lt;a href=&quot;#cb1-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;st&quot;&gt;&amp;#39;{t[$2] = t[$2] &amp;gt; $1 ? t[$2] : $1}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-3&quot;&gt;&lt;a href=&quot;#cb1-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;st&quot;&gt;   END {&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-4&quot;&gt;&lt;a href=&quot;#cb1-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;st&quot;&gt;     PROCINFO[&amp;quot;sorted_in&amp;quot;] = &amp;quot;@val_num_asc&amp;quot;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-5&quot;&gt;&lt;a href=&quot;#cb1-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;st&quot;&gt;     for (key in t) {&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-6&quot;&gt;&lt;a href=&quot;#cb1-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;st&quot;&gt;       printf &amp;quot;%s\t%s\n&amp;quot;, strftime(&amp;quot;%F&amp;quot;, t[key]), key&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-7&quot;&gt;&lt;a href=&quot;#cb1-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;st&quot;&gt;     }&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-8&quot;&gt;&lt;a href=&quot;#cb1-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;st&quot;&gt;   }&amp;#39;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;And here’s how the output looks like:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;2007-07-30      .gkrellm2
2007-08-04      .gobby
2007-08-17      .imgseek
2007-08-25      .kderc
2007-09-12      .ftp_banner
2007-09-18      .BitchX
...&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Thank you to numerous StackOverflow users from whose questions and
answers I benefited; in particular the ones about &lt;a
href=&quot;https://stackoverflow.com/a/17580855/110081&quot;&gt;printing mtime from
find&lt;/a&gt; and &lt;a
href=&quot;https://stackoverflow.com/a/29005234/110081&quot;&gt;sorting an AWK
array&lt;/a&gt;.&lt;/p&gt;
</description>
                        <pubDate>Fri, 04 Dec 2020 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2020-12-04-sort-directories-by-newest-file</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2020-12-04-sort-directories-by-newest-file.html</guid>
                </item>
        
                <item>
                        <title>Don&apos;t buy tempered glass PC cases</title>
                        <description>&lt;p&gt;For my new desktop PC, I got the &lt;a
href=&quot;https://www.bequiet.com/en/case/1717&quot;&gt;PURE BASE 500 Window
Black&lt;/a&gt; case from “be quiet!”. On the first day of trying to use it,
here’s what happened after a small bump of the edge against the
floor:&lt;/p&gt;
&lt;figure&gt;
&lt;img src=&quot;/img/bequiet-glass.jpeg&quot;
alt=&quot;Shattered glass side panel of a desktop case&quot; /&gt;
&lt;figcaption aria-hidden=&quot;true&quot;&gt;Shattered glass side panel of a desktop
case&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;It may not be obvious from the picture, but it’s not like the panel
was usable in this state: it started to crumble even while I was
carrying it to the trash can.&lt;/p&gt;
&lt;p&gt;Moreover, the Ukrainian dealership of “be quiet!” doesn’t have any
replacement, glass or otherwise.&lt;/p&gt;
&lt;p&gt;Admittedly, it was a mistake to try to put on the side panel
vertically — I should have laid the case on its other side, put the
glass panel on top, and driven the screws while the panel was resting on
the case and could not fall. Expensive lesson learned. But I certainly
did not expect the glass for PC cases to be that fragile.&lt;/p&gt;
&lt;p&gt;Here are some other shattered glass PC cases I found on reddit:&lt;/p&gt;
&lt;figure&gt;
&lt;img src=&quot;/img/shattered-pc-glass/1.jpeg&quot; alt=&quot;Source&quot; /&gt;
&lt;figcaption aria-hidden=&quot;true&quot;&gt;&lt;a
href=&quot;https://www.reddit.com/r/buildapc/comments/6w9h05/shattered_tempered_glass_on_case_where_to_go_from/&quot;&gt;Source&lt;/a&gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
&lt;img src=&quot;/img/shattered-pc-glass/2.jpeg&quot; alt=&quot;Source&quot; /&gt;
&lt;figcaption aria-hidden=&quot;true&quot;&gt;&lt;a
href=&quot;https://www.reddit.com/r/Wellthatsucks/comments/jbxswv/tempered_glass_panel_on_my_pc_spontaneously/&quot;&gt;Source&lt;/a&gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
&lt;img src=&quot;/img/shattered-pc-glass/3.jpeg&quot; alt=&quot;Source&quot; /&gt;
&lt;figcaption aria-hidden=&quot;true&quot;&gt;&lt;a
href=&quot;https://www.reddit.com/r/Wellthatsucks/comments/jpn226/accidentally_pulled_on_the_headphones_wire_and/&quot;&gt;Source&lt;/a&gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
&lt;img src=&quot;/img/shattered-pc-glass/4.jpeg&quot; alt=&quot;Source&quot; /&gt;
&lt;figcaption aria-hidden=&quot;true&quot;&gt;&lt;a
href=&quot;https://www.reddit.com/r/buildapc/comments/a495i3/corsair_crystal_570x_one_of_the_side_panel_glass/&quot;&gt;Source&lt;/a&gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
&lt;img src=&quot;/img/shattered-pc-glass/5.jpeg&quot; alt=&quot;Source&quot; /&gt;
&lt;figcaption aria-hidden=&quot;true&quot;&gt;&lt;a
href=&quot;https://www.reddit.com/r/Wellthatsucks/comments/j3lsbb/pc_glass_shattered_for_no_reason/&quot;&gt;Source&lt;/a&gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
&lt;img src=&quot;/img/shattered-pc-glass/6.jpeg&quot; alt=&quot;Source&quot; /&gt;
&lt;figcaption aria-hidden=&quot;true&quot;&gt;&lt;a
href=&quot;https://www.reddit.com/r/Wellthatsucks/comments/b33wrz/when_you_save_up_for_months_to_buy_pc_parts_and/&quot;&gt;Source&lt;/a&gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
&lt;img src=&quot;/img/shattered-pc-glass/7.jpeg&quot; alt=&quot;Source&quot; /&gt;
&lt;figcaption aria-hidden=&quot;true&quot;&gt;&lt;a
href=&quot;https://www.reddit.com/r/Wellthatsucks/comments/cumil8/my_computer_cases_glass_panel_just_shattered_in/&quot;&gt;Source&lt;/a&gt;&lt;/figcaption&gt;
&lt;/figure&gt;
</description>
                        <pubDate>Tue, 03 Nov 2020 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2020-11-03-bequiet-tempered-glass</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2020-11-03-bequiet-tempered-glass.html</guid>
                </item>
        
                <item>
                        <title>Avoid the months() and years() functions from lubridate</title>
                        <description>&lt;p&gt;&lt;a href=&quot;https://lubridate.tidyverse.org/&quot;&gt;lubridate&lt;/a&gt; is an
R/tidyverse package for dealing with dates and times.&lt;/p&gt;
&lt;p&gt;One of its nice features is the date arithmetics: you can take a
date, such as &lt;code&gt;ymd(&quot;2020-08-30&quot;)&lt;/code&gt;, add an interval (such as
&lt;code&gt;days(10)&lt;/code&gt;), and get a new date
(&lt;code&gt;&quot;2020-09-09&quot;&lt;/code&gt;).&lt;/p&gt;
&lt;p&gt;In addition to &lt;code&gt;days()&lt;/code&gt;, you can modify dates with
&lt;code&gt;months()&lt;/code&gt; and &lt;code&gt;years()&lt;/code&gt;. However, I would argue
you almost never want to use these two functions.&lt;/p&gt;
&lt;p&gt;I am writing this on August 30, 2020. I’d like to do some forecasting
6 months ahead. So I would do&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt; today() + months(6)
[1] NA&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The reason is that, strictly speaking, 6 months for now would be
February 30, 2021, which does not exist.&lt;/p&gt;
&lt;p&gt;Here’s the relevant section of the &lt;a
href=&quot;https://cran.r-project.org/web/packages/lubridate/vignettes/lubridate.html&quot;&gt;vignette&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;h3&gt;
If anyone drove a time machine, they would crash
&lt;/h3&gt;
&lt;p&gt;
The length of months and years change so often that doing arithmetic
with them can be unintuitive. Consider a simple operation, &lt;code&gt;January
31st + one month&lt;/code&gt;. Should the answer be
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;February 31st&lt;/code&gt; (which doesn’t exist)
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;March 4th&lt;/code&gt; (31 days after January 31), or
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;February 28th&lt;/code&gt; (assuming its not a leap year)
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
A basic property of arithmetic is that &lt;code&gt;a + b - b = a&lt;/code&gt;. Only
solution 1 obeys this property, but it is an invalid date. I’ve tried to
make lubridate as consistent as possible by invoking the following rule
&lt;em&gt;if adding or subtracting a month or a year creates an invalid date,
lubridate will return an NA&lt;/em&gt;. This is new with version 1.3.0, so if
you’re an old hand with lubridate be sure to remember this!
&lt;/p&gt;
&lt;p&gt;
If you thought solution 2 or 3 was more useful, no problem. You can
still get those results with clever arithmetic, or by using the special
&lt;code&gt;%m+%&lt;/code&gt; and &lt;code&gt;%m-%&lt;/code&gt; operators. &lt;code&gt;%m+%&lt;/code&gt; and
&lt;code&gt;%m-%&lt;/code&gt; automatically roll dates back to the last day of the
month, should that be necessary.
&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;r&quot;&gt;&lt;span class=&quot;identifier&quot;&gt;jan31&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;identifier&quot;&gt;ymd&lt;/span&gt;&lt;span class=&quot;paren&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&quot;2013-01-31&quot;&lt;/span&gt;&lt;span class=&quot;paren&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;identifier&quot;&gt;jan31&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;identifier&quot;&gt;months&lt;/span&gt;&lt;span class=&quot;paren&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;number&quot;&gt;11&lt;/span&gt;&lt;span class=&quot;paren&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;comment&quot;&gt;#&amp;gt;  [1] &quot;2013-01-31&quot; NA           &quot;2013-03-31&quot; NA           &quot;2013-05-31&quot;&lt;/span&gt;
&lt;span class=&quot;comment&quot;&gt;#&amp;gt;  [6] NA           &quot;2013-07-31&quot; &quot;2013-08-31&quot; NA           &quot;2013-10-31&quot;&lt;/span&gt;
&lt;span class=&quot;comment&quot;&gt;#&amp;gt; [11] NA           &quot;2013-12-31&quot;&lt;/span&gt;
&lt;span class=&quot;identifier&quot;&gt;floor_date&lt;/span&gt;&lt;span class=&quot;paren&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;identifier&quot;&gt;jan31&lt;/span&gt;, &lt;span class=&quot;string&quot;&gt;&quot;month&quot;&lt;/span&gt;&lt;span class=&quot;paren&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;identifier&quot;&gt;months&lt;/span&gt;&lt;span class=&quot;paren&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;number&quot;&gt;11&lt;/span&gt;&lt;span class=&quot;paren&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;identifier&quot;&gt;days&lt;/span&gt;&lt;span class=&quot;paren&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;number&quot;&gt;31&lt;/span&gt;&lt;span class=&quot;paren&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;comment&quot;&gt;#&amp;gt;  [1] &quot;2013-02-01&quot; &quot;2013-03-04&quot; &quot;2013-04-01&quot; &quot;2013-05-02&quot; &quot;2013-06-01&quot;&lt;/span&gt;
&lt;span class=&quot;comment&quot;&gt;#&amp;gt;  [6] &quot;2013-07-02&quot; &quot;2013-08-01&quot; &quot;2013-09-01&quot; &quot;2013-10-02&quot; &quot;2013-11-01&quot;&lt;/span&gt;
&lt;span class=&quot;comment&quot;&gt;#&amp;gt; [11] &quot;2013-12-02&quot; &quot;2014-01-01&quot;&lt;/span&gt;
&lt;span class=&quot;identifier&quot;&gt;jan31&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;%m+%&lt;/span&gt; &lt;span class=&quot;identifier&quot;&gt;months&lt;/span&gt;&lt;span class=&quot;paren&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;number&quot;&gt;11&lt;/span&gt;&lt;span class=&quot;paren&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;comment&quot;&gt;#&amp;gt;  [1] &quot;2013-01-31&quot; &quot;2013-02-28&quot; &quot;2013-03-31&quot; &quot;2013-04-30&quot; &quot;2013-05-31&quot;&lt;/span&gt;
&lt;span class=&quot;comment&quot;&gt;#&amp;gt;  [6] &quot;2013-06-30&quot; &quot;2013-07-31&quot; &quot;2013-08-31&quot; &quot;2013-09-30&quot; &quot;2013-10-31&quot;&lt;/span&gt;
&lt;span class=&quot;comment&quot;&gt;#&amp;gt; [11] &quot;2013-11-30&quot; &quot;2013-12-31&quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;
Notice that this will only affect arithmetic with months (and arithmetic
with years if your start date it Feb 29).
&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Now, can you think of some applications where this behavior —
returning an &lt;code&gt;NA&lt;/code&gt; — would be the desired return value of the
expression &lt;code&gt;today() + months(6)&lt;/code&gt;?&lt;/p&gt;
&lt;p&gt;These functions are especially dangerous because they work &lt;em&gt;most
of the time&lt;/em&gt;. So when you are testing your code, you’ll likely see
it working. And then once a couple of months it will fail.&lt;/p&gt;
&lt;p&gt;So I am trying to get into the habit of writing
&lt;code&gt;days(6*30)&lt;/code&gt; instead of &lt;code&gt;months(6)&lt;/code&gt;.
Alternatively, you can try to remember to use &lt;code&gt;%m+%&lt;/code&gt; instead
of &lt;code&gt;+&lt;/code&gt;, although I’m sure you will slip up sooner or
later.&lt;/p&gt;
&lt;p&gt;The date arithmetic in lubridate is very neat and simple
syntactically, and I think it was a mistake to make the most
natural-looking construct fail 2% of time. Even removing those functions
from the API would be better — as it would make it impossible to write
the subtly-incorrect code.&lt;/p&gt;
</description>
                        <pubDate>Sun, 30 Aug 2020 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2020-08-30-lubridate-months</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2020-08-30-lubridate-months.html</guid>
                </item>
        
                <item>
                        <title>Configuring PulseAudio for Audient EVO 4</title>
                        <description>&lt;p&gt;For about a month now, I’ve been using the &lt;a
href=&quot;https://evo.audio/products/evo-4/overview/&quot;&gt;Audient EVO 4&lt;/a&gt;
audio interface. One of its features is “audio loopback”, where it can
capture your computer audio and send it as if it were coming from your
microphone.&lt;/p&gt;
&lt;p&gt;Unfortunately, when used with its default PulseAudio configuration on
Linux, this feature is turned on by default. As a result, your peers on
a video call will be hearing themselves (unless an echo-cancellation
algorithm of the video call service interferes).&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://iotcl.com/&quot;&gt;Toon Claes&lt;/a&gt; ran into the same problem
and published &lt;a
href=&quot;https://writepermission.com/evo4-pulseaudio-profile.html&quot;&gt;his
solution&lt;/a&gt;. It was a great starting point for me, but it didn’t quite
work in my case, so here I am publishing a rather simpler configuration
that does work for me. (Note that this configuration does not support
the audio loopback feature. If needed, it can be set up directly in
PulseAudio by using its loopback module.)&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;&lt;p&gt;Put the following in
&lt;code&gt;/etc/udev/rules.d/91-pulseaudio-custom-profiles.rules&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SUBSYSTEM==&amp;quot;sound&amp;quot;, SUBSYSTEMS==&amp;quot;usb&amp;quot;, ACTION==&amp;quot;change&amp;quot;, KERNEL==&amp;quot;card*&amp;quot;, ENV{ID_VENDOR}==&amp;quot;Audient&amp;quot;, ENV{ID_MODEL}==&amp;quot;EVO4&amp;quot;, ENV{PULSE_PROFILE_SET}=&amp;quot;/etc/pulse/profile-sets/audient-evo4.conf&amp;quot;&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Put the following in
&lt;code&gt;/etc/pulse/profile-sets/audient-evo4.conf&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[General]
auto-profiles = no

[Mapping mic-input]
description = Mic
device-strings = hw:%f
channel-map = mono,mono,aux0,aux1
paths-input = analog-input-mic
direction = input
priority = 1

[Mapping stereo-output]
description = Stereo output
device-strings = front:%f
channel-map = front-left,front-right,aux3,aux4
paths-output = analog-output
direction = output
priority = 1

[Profile output:stereo-output+input:mic-input]
description = Stereo Output + Mic Input
output-mappings = stereo-output
input-mappings = mic-input
priority = 100
skip-probe = yes&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Put the following in
&lt;code&gt;~/.config/pulse/daemon.conf&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;remixing-use-all-sink-channels = no&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Apply the settings:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo udevadm control --reload
sudo udevadm trigger --subsystem-match=sound
pulseaudio --kill&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;/ol&gt;
</description>
                        <pubDate>Fri, 10 Jul 2020 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2020-07-10-audient-evo4-pulseaudio</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2020-07-10-audient-evo4-pulseaudio.html</guid>
                </item>
        
                <item>
                        <title>How I integrate ghcid with vim/neovim</title>
                        <description>&lt;p&gt;&lt;a href=&quot;https://github.com/ndmitchell/ghcid&quot;&gt;ghcid&lt;/a&gt; by Neil
Mitchell is a simple but robust tool to get instant error messages for
your Haskell code.&lt;/p&gt;
&lt;p&gt;For the most part, it doesn’t require any integration with your
editor or IDE, which is exactly what makes it robust—if you can run
ghci, you can run ghcid. There’s one feature though for which the editor
and ghcid have to talk to one another: the ability to quickly jump to
the location of the error.&lt;/p&gt;
&lt;p&gt;The “official” way to integrate ghcid with neovim is &lt;a
href=&quot;https://github.com/ndmitchell/ghcid/tree/master/plugins/nvim&quot;&gt;the
plugin&lt;/a&gt;. However, the plugin insists on running ghcid from within
nvim, which makes the whole thing less robust. For instance, I often
need to run ghci/ghcid in a different environment than my editor, like
in a nix shell or a docker container.&lt;/p&gt;
&lt;p&gt;Therefore, I use a simpler, plugin-less setup. After all, vim/nvim
already have a feature to read the compiler output, called &lt;a
href=&quot;https://neovim.io/doc/user/quickfix.html&quot;&gt;quickfix&lt;/a&gt;, and ghcid
is able to write ghci’s output to a file. All we need is a few tweaks to
make them play well together. This article describes the setup, which
I’ve been happily using for 1.5 years now.&lt;/p&gt;
&lt;h2 id=&quot;ghcid-setup&quot;&gt;ghcid setup&lt;/h2&gt;
&lt;p&gt;ghcid passes some flags to ghci which makes its output a bit harder
to parse.&lt;/p&gt;
&lt;p&gt;Therefore, I build a modified version of ghcid, with a different
default set of flags.&lt;/p&gt;
&lt;p&gt;(There are probably ways to achieve this that do not require
recompiling ghcid, but this is what I prefer—so that when I run ghcid,
it simply does what I want.)&lt;/p&gt;
&lt;p&gt;The patch you need to apply is very simple:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb1&quot;&gt;&lt;pre
class=&quot;sourceCode diff&quot;&gt;&lt;code class=&quot;sourceCode diff&quot;&gt;&lt;span id=&quot;cb1-1&quot;&gt;&lt;a href=&quot;#cb1-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;--- src/Ghcid.hs&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-2&quot;&gt;&lt;a href=&quot;#cb1-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;dt&quot;&gt;+++ src/Ghcid.hs&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-3&quot;&gt;&lt;a href=&quot;#cb1-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;dt&quot;&gt;@@ -97,7 +97,7 @@ options = cmdArgsMode $ Options&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-4&quot;&gt;&lt;a href=&quot;#cb1-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;     ,restart = [] &amp;amp;= typ &amp;quot;PATH&amp;quot; &amp;amp;= help &amp;quot;Restart the command when the given file or directory contents change (defaults to .ghci and any .cabal file, unless when using stack or a custom command)&amp;quot;&lt;/span&gt;
&lt;span id=&quot;cb1-5&quot;&gt;&lt;a href=&quot;#cb1-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;     ,reload = [] &amp;amp;= typ &amp;quot;PATH&amp;quot; &amp;amp;= help &amp;quot;Reload when the given file or directory contents change (defaults to none)&amp;quot;&lt;/span&gt;
&lt;span id=&quot;cb1-6&quot;&gt;&lt;a href=&quot;#cb1-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;     ,directory = &amp;quot;.&amp;quot; &amp;amp;= typDir &amp;amp;= name &amp;quot;C&amp;quot; &amp;amp;= help &amp;quot;Set the current directory&amp;quot;&lt;/span&gt;
&lt;span id=&quot;cb1-7&quot;&gt;&lt;a href=&quot;#cb1-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;st&quot;&gt;-    ,outputfile = [] &amp;amp;= typFile &amp;amp;= name &amp;quot;o&amp;quot; &amp;amp;= help &amp;quot;File to write the full output to&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-8&quot;&gt;&lt;a href=&quot;#cb1-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;va&quot;&gt;+    ,outputfile = [&amp;quot;quickfix&amp;quot;] &amp;amp;= typFile &amp;amp;= name &amp;quot;o&amp;quot; &amp;amp;= help &amp;quot;File to write the full output to&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-9&quot;&gt;&lt;a href=&quot;#cb1-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;     ,ignoreLoaded = False &amp;amp;= explicit &amp;amp;= name &amp;quot;ignore-loaded&amp;quot; &amp;amp;= help &amp;quot;Keep going if no files are loaded. Requires --reload to be set.&amp;quot;&lt;/span&gt;
&lt;span id=&quot;cb1-10&quot;&gt;&lt;a href=&quot;#cb1-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;     ,poll = Nothing &amp;amp;= typ &amp;quot;SECONDS&amp;quot; &amp;amp;= opt &amp;quot;0.1&amp;quot; &amp;amp;= explicit &amp;amp;= name &amp;quot;poll&amp;quot; &amp;amp;= help &amp;quot;Use polling every N seconds (defaults to using notifiers)&amp;quot;&lt;/span&gt;
&lt;span id=&quot;cb1-11&quot;&gt;&lt;a href=&quot;#cb1-11&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;     ,max_messages = Nothing &amp;amp;= name &amp;quot;n&amp;quot; &amp;amp;= help &amp;quot;Maximum number of messages to print&amp;quot;&lt;/span&gt;
&lt;span id=&quot;cb1-12&quot;&gt;&lt;a href=&quot;#cb1-12&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;--- src/Language/Haskell/Ghcid/Util.hs&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-13&quot;&gt;&lt;a href=&quot;#cb1-13&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;dt&quot;&gt;+++ src/Language/Haskell/Ghcid/Util.hs&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-14&quot;&gt;&lt;a href=&quot;#cb1-14&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;dt&quot;&gt;@@ -47,7 +47,8 @@ ghciFlagsRequiredVersioned =&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-15&quot;&gt;&lt;a href=&quot;#cb1-15&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt; -- | Flags that make ghcid work better and are supported on all GHC versions&lt;/span&gt;
&lt;span id=&quot;cb1-16&quot;&gt;&lt;a href=&quot;#cb1-16&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt; ghciFlagsUseful :: [String]&lt;/span&gt;
&lt;span id=&quot;cb1-17&quot;&gt;&lt;a href=&quot;#cb1-17&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt; ghciFlagsUseful =&lt;/span&gt;
&lt;span id=&quot;cb1-18&quot;&gt;&lt;a href=&quot;#cb1-18&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;st&quot;&gt;-    [&amp;quot;-ferror-spans&amp;quot; -- see #148&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-19&quot;&gt;&lt;a href=&quot;#cb1-19&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;va&quot;&gt;+    [&amp;quot;-fno-error-spans&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-20&quot;&gt;&lt;a href=&quot;#cb1-20&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;va&quot;&gt;+    ,&amp;quot;-fno-diagnostics-show-caret&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-21&quot;&gt;&lt;a href=&quot;#cb1-21&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;     ,&amp;quot;-j&amp;quot; -- see #153, GHC 7.8 and above, but that&amp;#39;s all I support anyway&lt;/span&gt;
&lt;span id=&quot;cb1-22&quot;&gt;&lt;a href=&quot;#cb1-22&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;     ]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Alternatively, you can clone my fork of ghcid at &lt;a
href=&quot;https://github.com/UnkindPartition/ghcid&quot;
class=&quot;uri&quot;&gt;https://github.com/UnkindPartition/ghcid&lt;/a&gt;, which already
contains the patch.&lt;/p&gt;
&lt;p&gt;Apart from changing the default flags passed to ghci, it also tells
ghcid to write the ghci output to the file called &lt;code&gt;quickfix&lt;/code&gt;
by default, so that you don’t have to write &lt;code&gt;-o quickfix&lt;/code&gt; on
the command line every time.&lt;/p&gt;
&lt;h2 id=&quot;vimneovim-setup&quot;&gt;vim/neovim setup&lt;/h2&gt;
&lt;p&gt;Here are the vim pieces that you’ll need to put into your
&lt;code&gt;.vimrc&lt;/code&gt; or &lt;code&gt;init.vim&lt;/code&gt;. First, set the
&lt;code&gt;errorformat&lt;/code&gt; option to tell vim how to parse ghci’s error
messages:&lt;/p&gt;
&lt;pre class=&quot;viml&quot;&gt;&lt;code&gt;set errorformat=%C%*\\s•\ %m,
               \%-C\ %.%#,
               \%A%f:%l:%c:\ %t%.%#&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Don’t ask me how it works—it’s been a long time since I wrote it—but
it works.&lt;/p&gt;
&lt;p&gt;Next, I prefer to define a few keybindings that make quickfix’ing
easier:&lt;/p&gt;
&lt;pre class=&quot;viml&quot;&gt;&lt;code&gt;map &amp;lt;F5&amp;gt; :cfile quickfix&amp;lt;CR&amp;gt;
map &amp;lt;C-j&amp;gt; :cnext&amp;lt;CR&amp;gt;
map &amp;lt;C-k&amp;gt; :cprevious&amp;lt;CR&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When I see any errors in the ghcid window, I press &lt;code&gt;F5&lt;/code&gt; to
load them into vim and jump to the first error. Then, if I need to, I
use Ctrl-j and Ctrl-k to jump between different errors.&lt;/p&gt;
</description>
                        <pubDate>Wed, 08 Jul 2020 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2020-07-08-integrate-ghcid-vim</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2020-07-08-integrate-ghcid-vim.html</guid>
                </item>
        
                <item>
                        <title>Which dynamic mic should you buy?</title>
                        <description>&lt;p&gt;Shawn Milochik has published a cool &lt;a
href=&quot;https://aoeus.com/dyn2/&quot;&gt;blind test of dynamic microphones&lt;/a&gt;. Go
take it yourself and choose which ones you prefer.&lt;/p&gt;
&lt;p&gt;But also, if you don’t have time for that or would like to know what
I think, here’s my rating of Shawn’s dynamic mics based on his
recordings.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Favorite&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Shure SM7B ($400)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Very good&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Samson Q2U ($60)&lt;/li&gt;
&lt;li&gt;Electro-Voice RE20 ($450)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Good&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Behringer XM8500 ($23)&lt;/li&gt;
&lt;li&gt;Sennheiser MD 441U ($900)&lt;/li&gt;
&lt;li&gt;Rode Procaster ($230)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Least favorite&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Sennheiser MD 421-II ($380)&lt;/li&gt;
&lt;li&gt;Heil PR40 ($330)&lt;/li&gt;
&lt;li&gt;Sennheiser e 835-S ($100)&lt;/li&gt;
&lt;li&gt;Rode PodMic ($100)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I’m not publishing the correspondence between the microphone models
and Shawn’s codenames so that you can still take the test. I added the
retail prices of these microphones in USD (mostly based on Sweetwater)
for a quick reference.&lt;/p&gt;
&lt;p&gt;The usual disclaimer is that the way a mic sounds depends on the
voice, but I would think these results are generalizable at least to
some extent. Shure SM7B once again has proven its dominance, and Samson
Q2U its value for money.&lt;/p&gt;
</description>
                        <pubDate>Sat, 13 Jun 2020 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2020-06-13-which-dynamic-mic</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2020-06-13-which-dynamic-mic.html</guid>
                </item>
        
                <item>
                        <title>Visualizing Haskell heap profiles in 2020</title>
                        <description>&lt;p&gt;Heap profiling is a feature of the Glasgow Haskell Compiler (GHC)
that lets a program record its own memory usage by type, module, cost
center, or other attribute, and write it to a &lt;code&gt;program.hp&lt;/code&gt;
file.&lt;/p&gt;
&lt;p&gt;Here I review the existing tools—and introduce a new one—for
visualizing and analyzing these profiles.&lt;/p&gt;
&lt;h2 id=&quot;hp2ps&quot;&gt;hp2ps&lt;/h2&gt;
&lt;p&gt;hp2ps is the standard heap profile visualizer, as it comes bundled
with GHC.&lt;/p&gt;
&lt;p&gt;Run it as&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;hp2ps -c benchmark.hp&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;(where &lt;code&gt;-c&lt;/code&gt; makes the output colored), and it will produce
the file &lt;code&gt;benchmark.ps&lt;/code&gt;, which you can open with many
document viewers.&lt;/p&gt;
&lt;p&gt;Here’s what the output looks like:&lt;/p&gt;
&lt;figure&gt;
&lt;img src=&quot;/img/hp2ps.svg&quot; alt=&quot;An example graph produced by hp2ps&quot; /&gt;
&lt;figcaption aria-hidden=&quot;true&quot;&gt;An example graph produced by
hp2ps&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;The example shows a heap profile by the &lt;em&gt;cost center&lt;/em&gt; stack
that allocated the data. As I mentioned, there are many other types of
heap profiles, but this is what I’ll be using here as an example.&lt;/p&gt;
&lt;p&gt;As you see, the cost centers on the right are truncated. I usually
like to see them longer. They are actually truncated by the profiled
program itself, not by the visualizer, so to get longer profiles, rerun
your program with &lt;code&gt;+RTS -hc -L500&lt;/code&gt; to increase the maximum
length from the default 25 to, say, 500.&lt;/p&gt;
&lt;p&gt;However, hp2ps doesn’t deal well with long cost center stacks (or
other long identifiers) by default: the whole page would be filled with
identifiers, and there would be no room left for the graph itself. To
work around that, pass &lt;code&gt;-M&lt;/code&gt; to hp2ps. It produces a two-page
.ps file, with the legend on the first page and the graph on the second
one.&lt;/p&gt;
&lt;p&gt;I found that viewers like Okular and Evince only display the second
page of the two-page .ps file, but it works if you first convert the
output to pdf with ps2pdf. Here’s what the output looks like:&lt;/p&gt;
&lt;figure&gt;
&lt;img src=&quot;/img/hp2ps-page1.svg&quot; /&gt; &lt;img src=&quot;/img/hp2ps-page2.svg&quot; /&gt;
&lt;figcaption&gt;
Two-page output from hp2ps -M
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h2 id=&quot;hp2pretty&quot;&gt;hp2pretty&lt;/h2&gt;
&lt;p&gt;hp2pretty by Claude Heiland-Allen has a few advantages over hp2ps: a
nicer output with transparency and grid lines, truncation of long cost
center stacks, and the ability to write the full cost center stacks to a
file using a &lt;code&gt;--key&lt;/code&gt; option.&lt;/p&gt;
&lt;p&gt;Run it simply as&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;hp2pretty benchmark.hp&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;and it will produce a file named &lt;code&gt;benchmark.svg&lt;/code&gt;.&lt;/p&gt;
&lt;figure&gt;
&lt;img src=&quot;/img/hp2pretty.svg&quot; alt=&quot;Example output of hp2pretty&quot; /&gt;
&lt;figcaption aria-hidden=&quot;true&quot;&gt;Example output of hp2pretty&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h2 id=&quot;hpd3.js&quot;&gt;hp/D3.js&lt;/h2&gt;
&lt;p&gt;hp/D3.js by Edward Z. Yang is an online tool to visualize Haskell
heap profiles. There’s a hosted version at &lt;a
href=&quot;http://heap.ezyang.com/&quot;&gt;heap.ezyang.com&lt;/a&gt;, and there is &lt;a
href=&quot;https://github.com/ezyang/hpd3js&quot;&gt;the source code&lt;/a&gt; on
GitHub.&lt;/p&gt;
&lt;p&gt;I wasn’t able to build the source code due to the dependency on
hp2any (see below), but the hosted version still works. The disadvantage
of the hosted version is that you have to upload your heap profile to
the server, and it becomes public—consider this when working on
proprietary projects. (The profile files do not contain any source code,
but even the function names and call stacks may reveal too much
information in some cases.)&lt;/p&gt;
&lt;p&gt;hp/D3.js offers a choice of three different styles of pretty graphs
shown below. You can also &lt;a
href=&quot;http://heap.ezyang.com/view/f267b68e008f3f5cc64a088106f8882ec8f097c6&quot;&gt;browse
this profile&lt;/a&gt; yourself. There are some cool interactive features,
like the entry’s name or call stack being highlighted when you hover the
corresponding part of the graph.&lt;/p&gt;
&lt;figure&gt;
&lt;img src=&quot;/img/hpd3js-1.png&quot; alt=&quot;hp/d3.js: stacked graph&quot; /&gt;
&lt;figcaption aria-hidden=&quot;true&quot;&gt;hp/d3.js: stacked graph&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
&lt;img src=&quot;/img/hpd3js-2.png&quot; alt=&quot;hp/d3.js: normalized stacked graph&quot; /&gt;
&lt;figcaption aria-hidden=&quot;true&quot;&gt;hp/d3.js: normalized stacked
graph&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
&lt;img src=&quot;/img/hpd3js-3.png&quot; alt=&quot;hp/d3.js: overlayed area graph&quot; /&gt;
&lt;figcaption aria-hidden=&quot;true&quot;&gt;hp/d3.js: overlayed area
graph&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h2 id=&quot;perl-r&quot;&gt;Perl &amp;amp; R&lt;/h2&gt;
&lt;p&gt;Sometimes a quick look at the heap profile graph is all you need to
understand what to do next. Other times, a more detailed analysis is
required. In such cases, my favorite way is to convert an .hp file to
csv and load it into R.&lt;/p&gt;
&lt;p&gt;To convert an .hp file to csv, I wrote a short Perl script, &lt;a
href=&quot;/files/2020-05-14-visualize-haskell-heap-profiles/hp2csv&quot;&gt;hp2csv&lt;/a&gt;.
(Unlike many tools written in Haskell, there’s a good chance it’ll
continue working in 10 years.) Put it somewhere in your PATH, make it
executable (&lt;code&gt;chmod +x ~/bin/hp2csv&lt;/code&gt;), and run&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;hp2csv benchmark.hp &amp;gt; benchmark.csv&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The CSV has a simple format:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;time,name,value
0.094997,(487)getElements/CAF:getElements,40
0.094997,(415)CAF:$cfoldl&amp;#39;_r3hK,32
0.094997,(412)CAF:$ctoList_r3hH,32
0.094997,(482)match/main/Main.CAF,24
0.094997,(480)main/Main.CAF,32&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;where &lt;code&gt;time&lt;/code&gt; is the time in seconds since the program
start, &lt;code&gt;name&lt;/code&gt; is the name of the cost center/type/etc.
(depending on what kind of heap profiling you did), and
&lt;code&gt;value&lt;/code&gt; is the number of bytes.&lt;/p&gt;
&lt;p&gt;Now let’s load this into R and try to reproduce the above graphs
using ggplot.&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb5&quot;&gt;&lt;pre class=&quot;sourceCode r&quot;&gt;&lt;code class=&quot;sourceCode r&quot;&gt;&lt;span id=&quot;cb5-1&quot;&gt;&lt;a href=&quot;#cb5-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;fu&quot;&gt;library&lt;/span&gt;(tidyverse)&lt;/span&gt;
&lt;span id=&quot;cb5-2&quot;&gt;&lt;a href=&quot;#cb5-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;fu&quot;&gt;library&lt;/span&gt;(scales) &lt;span class=&quot;co&quot;&gt;# for a somewhat better color scheme&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-3&quot;&gt;&lt;a href=&quot;#cb5-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-4&quot;&gt;&lt;a href=&quot;#cb5-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;csv &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;read_csv&lt;/span&gt;(&lt;span class=&quot;st&quot;&gt;&amp;quot;benchmark.csv&amp;quot;&lt;/span&gt;) &lt;span class=&quot;sc&quot;&gt;%&amp;gt;%&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-5&quot;&gt;&lt;a href=&quot;#cb5-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;co&quot;&gt;# convert bytes to megabytes&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-6&quot;&gt;&lt;a href=&quot;#cb5-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;fu&quot;&gt;mutate&lt;/span&gt;(&lt;span class=&quot;at&quot;&gt;value =&lt;/span&gt; value &lt;span class=&quot;sc&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;fl&quot;&gt;1e6&lt;/span&gt;) &lt;span class=&quot;sc&quot;&gt;%&amp;gt;%&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-7&quot;&gt;&lt;a href=&quot;#cb5-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;co&quot;&gt;# absent measurements are 0s&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-8&quot;&gt;&lt;a href=&quot;#cb5-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;fu&quot;&gt;complete&lt;/span&gt;(time,name, &lt;span class=&quot;at&quot;&gt;fill =&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;list&lt;/span&gt;(&lt;span class=&quot;at&quot;&gt;value =&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;0&lt;/span&gt;))&lt;/span&gt;
&lt;span id=&quot;cb5-9&quot;&gt;&lt;a href=&quot;#cb5-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;/span&gt;
&lt;span id=&quot;cb5-10&quot;&gt;&lt;a href=&quot;#cb5-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-11&quot;&gt;&lt;a href=&quot;#cb5-11&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;co&quot;&gt;# find top 15 entries and sort them&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-12&quot;&gt;&lt;a href=&quot;#cb5-12&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;top_names &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; csv &lt;span class=&quot;sc&quot;&gt;%&amp;gt;%&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-13&quot;&gt;&lt;a href=&quot;#cb5-13&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;fu&quot;&gt;group_by&lt;/span&gt;(name) &lt;span class=&quot;sc&quot;&gt;%&amp;gt;%&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-14&quot;&gt;&lt;a href=&quot;#cb5-14&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;fu&quot;&gt;summarize&lt;/span&gt;(&lt;span class=&quot;at&quot;&gt;sum_value =&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;sum&lt;/span&gt;(value)) &lt;span class=&quot;sc&quot;&gt;%&amp;gt;%&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-15&quot;&gt;&lt;a href=&quot;#cb5-15&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;fu&quot;&gt;arrange&lt;/span&gt;(&lt;span class=&quot;fu&quot;&gt;desc&lt;/span&gt;(sum_value)) &lt;span class=&quot;sc&quot;&gt;%&amp;gt;%&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-16&quot;&gt;&lt;a href=&quot;#cb5-16&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;fu&quot;&gt;head&lt;/span&gt;(&lt;span class=&quot;at&quot;&gt;n=&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;15&lt;/span&gt;) &lt;span class=&quot;sc&quot;&gt;%&amp;gt;%&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-17&quot;&gt;&lt;a href=&quot;#cb5-17&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;fu&quot;&gt;mutate&lt;/span&gt;(&lt;span class=&quot;at&quot;&gt;name_sorted =&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;str_trunc&lt;/span&gt;(name,&lt;span class=&quot;dv&quot;&gt;30&lt;/span&gt;),&lt;/span&gt;
&lt;span id=&quot;cb5-18&quot;&gt;&lt;a href=&quot;#cb5-18&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;         &lt;span class=&quot;at&quot;&gt;name_sorted =&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;factor&lt;/span&gt;(name_sorted, &lt;span class=&quot;at&quot;&gt;levels=&lt;/span&gt;name_sorted))&lt;/span&gt;
&lt;span id=&quot;cb5-19&quot;&gt;&lt;a href=&quot;#cb5-19&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;top_entries &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-20&quot;&gt;&lt;a href=&quot;#cb5-20&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;fu&quot;&gt;inner_join&lt;/span&gt;(csv, top_names, &lt;span class=&quot;at&quot;&gt;by=&lt;/span&gt;&lt;span class=&quot;st&quot;&gt;&amp;quot;name&amp;quot;&lt;/span&gt;)&lt;/span&gt;
&lt;span id=&quot;cb5-21&quot;&gt;&lt;a href=&quot;#cb5-21&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-22&quot;&gt;&lt;a href=&quot;#cb5-22&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;co&quot;&gt;# Create a custom color palette based on the &amp;#39;viridis&amp;#39; palette.&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-23&quot;&gt;&lt;a href=&quot;#cb5-23&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;co&quot;&gt;# Use &amp;#39;sample&amp;#39; to shuffle the colors,&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-24&quot;&gt;&lt;a href=&quot;#cb5-24&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;co&quot;&gt;# so that adjacent areas are not similarly colored.&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-25&quot;&gt;&lt;a href=&quot;#cb5-25&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;colors &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;cf&quot;&gt;function&lt;/span&gt;(n) {&lt;/span&gt;
&lt;span id=&quot;cb5-26&quot;&gt;&lt;a href=&quot;#cb5-26&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;fu&quot;&gt;set.seed&lt;/span&gt;(&lt;span class=&quot;dv&quot;&gt;2020&lt;/span&gt;)&lt;/span&gt;
&lt;span id=&quot;cb5-27&quot;&gt;&lt;a href=&quot;#cb5-27&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;fu&quot;&gt;sample&lt;/span&gt;(&lt;span class=&quot;fu&quot;&gt;viridis_pal&lt;/span&gt;(&lt;span class=&quot;at&quot;&gt;option=&lt;/span&gt;&lt;span class=&quot;st&quot;&gt;&amp;quot;A&amp;quot;&lt;/span&gt;,&lt;span class=&quot;at&quot;&gt;alpha=&lt;/span&gt;&lt;span class=&quot;fl&quot;&gt;0.7&lt;/span&gt;)(n))&lt;/span&gt;
&lt;span id=&quot;cb5-28&quot;&gt;&lt;a href=&quot;#cb5-28&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;}&lt;/span&gt;
&lt;span id=&quot;cb5-29&quot;&gt;&lt;a href=&quot;#cb5-29&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-30&quot;&gt;&lt;a href=&quot;#cb5-30&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;fu&quot;&gt;theme_set&lt;/span&gt;(&lt;span class=&quot;fu&quot;&gt;theme_bw&lt;/span&gt;())&lt;/span&gt;
&lt;span id=&quot;cb5-31&quot;&gt;&lt;a href=&quot;#cb5-31&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;fu&quot;&gt;ggplot&lt;/span&gt;(top_entries,&lt;span class=&quot;fu&quot;&gt;aes&lt;/span&gt;(time,value,&lt;span class=&quot;at&quot;&gt;fill=&lt;/span&gt;name_sorted)) &lt;span class=&quot;sc&quot;&gt;+&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-32&quot;&gt;&lt;a href=&quot;#cb5-32&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;fu&quot;&gt;geom_area&lt;/span&gt;(&lt;span class=&quot;at&quot;&gt;position=&lt;/span&gt;&lt;span class=&quot;st&quot;&gt;&amp;quot;stack&amp;quot;&lt;/span&gt;) &lt;span class=&quot;sc&quot;&gt;+&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-33&quot;&gt;&lt;a href=&quot;#cb5-33&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;fu&quot;&gt;discrete_scale&lt;/span&gt;(&lt;span class=&quot;at&quot;&gt;aesthetics =&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;quot;fill&amp;quot;&lt;/span&gt;,&lt;/span&gt;
&lt;span id=&quot;cb5-34&quot;&gt;&lt;a href=&quot;#cb5-34&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;                 &lt;span class=&quot;at&quot;&gt;scale_name =&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;quot;viridis modified&amp;quot;&lt;/span&gt;,&lt;/span&gt;
&lt;span id=&quot;cb5-35&quot;&gt;&lt;a href=&quot;#cb5-35&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;                 &lt;span class=&quot;at&quot;&gt;palette =&lt;/span&gt; colors) &lt;span class=&quot;sc&quot;&gt;+&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-36&quot;&gt;&lt;a href=&quot;#cb5-36&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;fu&quot;&gt;scale_y_continuous&lt;/span&gt;(&lt;span class=&quot;at&quot;&gt;breaks=&lt;/span&gt;&lt;span class=&quot;cf&quot;&gt;function&lt;/span&gt;(limits) &lt;span class=&quot;fu&quot;&gt;seq&lt;/span&gt;(&lt;span class=&quot;dv&quot;&gt;0&lt;/span&gt;, &lt;span class=&quot;fu&quot;&gt;floor&lt;/span&gt;(limits[[&lt;span class=&quot;dv&quot;&gt;2&lt;/span&gt;]]), &lt;span class=&quot;at&quot;&gt;by=&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;10&lt;/span&gt;)) &lt;span class=&quot;sc&quot;&gt;+&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-37&quot;&gt;&lt;a href=&quot;#cb5-37&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;fu&quot;&gt;labs&lt;/span&gt;(&lt;span class=&quot;at&quot;&gt;x=&lt;/span&gt;&lt;span class=&quot;st&quot;&gt;&amp;quot;seconds&amp;quot;&lt;/span&gt;, &lt;span class=&quot;at&quot;&gt;y=&lt;/span&gt;&lt;span class=&quot;st&quot;&gt;&amp;quot;MB&amp;quot;&lt;/span&gt;, &lt;span class=&quot;at&quot;&gt;fill =&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;quot;Cost center&amp;quot;&lt;/span&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;figure&gt;
&lt;img src=&quot;/img/heap-profile-ggplot-stacked.svg&quot;
alt=&quot;A stacked graph of the heap profile (produced with ggplot)&quot; /&gt;
&lt;figcaption aria-hidden=&quot;true&quot;&gt;A stacked graph of the heap profile
(produced with ggplot)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;But these stacked plots are not always the best way to represent the
data. Let’s see what happens if we try a simple line plot.&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb6&quot;&gt;&lt;pre class=&quot;sourceCode r&quot;&gt;&lt;code class=&quot;sourceCode r&quot;&gt;&lt;span id=&quot;cb6-1&quot;&gt;&lt;a href=&quot;#cb6-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;top_entries &lt;span class=&quot;sc&quot;&gt;%&amp;gt;%&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-2&quot;&gt;&lt;a href=&quot;#cb6-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;fu&quot;&gt;ggplot&lt;/span&gt;(&lt;span class=&quot;fu&quot;&gt;aes&lt;/span&gt;(time,value,&lt;span class=&quot;at&quot;&gt;color=&lt;/span&gt;name_sorted)) &lt;span class=&quot;sc&quot;&gt;+&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-3&quot;&gt;&lt;a href=&quot;#cb6-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;fu&quot;&gt;geom_line&lt;/span&gt;() &lt;span class=&quot;sc&quot;&gt;+&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-4&quot;&gt;&lt;a href=&quot;#cb6-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;fu&quot;&gt;scale_y_continuous&lt;/span&gt;(&lt;span class=&quot;at&quot;&gt;breaks=&lt;/span&gt;&lt;span class=&quot;cf&quot;&gt;function&lt;/span&gt;(limits) &lt;span class=&quot;fu&quot;&gt;seq&lt;/span&gt;(&lt;span class=&quot;dv&quot;&gt;0&lt;/span&gt;, &lt;span class=&quot;fu&quot;&gt;floor&lt;/span&gt;(limits[[&lt;span class=&quot;dv&quot;&gt;2&lt;/span&gt;]]), &lt;span class=&quot;at&quot;&gt;by=&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;5&lt;/span&gt;)) &lt;span class=&quot;sc&quot;&gt;+&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-5&quot;&gt;&lt;a href=&quot;#cb6-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;fu&quot;&gt;labs&lt;/span&gt;(&lt;span class=&quot;at&quot;&gt;x=&lt;/span&gt;&lt;span class=&quot;st&quot;&gt;&amp;quot;seconds&amp;quot;&lt;/span&gt;, &lt;span class=&quot;at&quot;&gt;y=&lt;/span&gt;&lt;span class=&quot;st&quot;&gt;&amp;quot;MB&amp;quot;&lt;/span&gt;, &lt;span class=&quot;at&quot;&gt;color =&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;quot;Cost center&amp;quot;&lt;/span&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;figure&gt;
&lt;img src=&quot;/img/heap-profile-ggplot-lines.svg&quot;
alt=&quot;A line graph of the heap profile&quot; /&gt;
&lt;figcaption aria-hidden=&quot;true&quot;&gt;A line graph of the heap
profile&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;This looks weird, doesn’t it? Do those lines merge, or does one of
them just disappear?&lt;/p&gt;
&lt;p&gt;To disentangle this graph a bit, we can add a random offset for each
cost-center.&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb7&quot;&gt;&lt;pre class=&quot;sourceCode r&quot;&gt;&lt;code class=&quot;sourceCode r&quot;&gt;&lt;span id=&quot;cb7-1&quot;&gt;&lt;a href=&quot;#cb7-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;fu&quot;&gt;set.seed&lt;/span&gt;(&lt;span class=&quot;dv&quot;&gt;2020&lt;/span&gt;)&lt;/span&gt;
&lt;span id=&quot;cb7-2&quot;&gt;&lt;a href=&quot;#cb7-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;top_entries &lt;span class=&quot;sc&quot;&gt;%&amp;gt;%&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb7-3&quot;&gt;&lt;a href=&quot;#cb7-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;fu&quot;&gt;group_by&lt;/span&gt;(name) &lt;span class=&quot;sc&quot;&gt;%&amp;gt;%&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb7-4&quot;&gt;&lt;a href=&quot;#cb7-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;fu&quot;&gt;mutate&lt;/span&gt;(&lt;span class=&quot;at&quot;&gt;value =&lt;/span&gt; value &lt;span class=&quot;sc&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;runif&lt;/span&gt;(&lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;,&lt;span class=&quot;dv&quot;&gt;0&lt;/span&gt;,&lt;span class=&quot;dv&quot;&gt;3&lt;/span&gt;)) &lt;span class=&quot;sc&quot;&gt;%&amp;gt;%&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb7-5&quot;&gt;&lt;a href=&quot;#cb7-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  ungroup &lt;span class=&quot;sc&quot;&gt;%&amp;gt;%&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb7-6&quot;&gt;&lt;a href=&quot;#cb7-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;fu&quot;&gt;ggplot&lt;/span&gt;(&lt;span class=&quot;fu&quot;&gt;aes&lt;/span&gt;(time,value,&lt;span class=&quot;at&quot;&gt;color=&lt;/span&gt;name_sorted)) &lt;span class=&quot;sc&quot;&gt;+&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb7-7&quot;&gt;&lt;a href=&quot;#cb7-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;fu&quot;&gt;geom_line&lt;/span&gt;() &lt;span class=&quot;sc&quot;&gt;+&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb7-8&quot;&gt;&lt;a href=&quot;#cb7-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;fu&quot;&gt;scale_y_continuous&lt;/span&gt;(&lt;span class=&quot;at&quot;&gt;breaks=&lt;/span&gt;&lt;span class=&quot;cf&quot;&gt;function&lt;/span&gt;(limits) &lt;span class=&quot;fu&quot;&gt;seq&lt;/span&gt;(&lt;span class=&quot;dv&quot;&gt;0&lt;/span&gt;, &lt;span class=&quot;fu&quot;&gt;floor&lt;/span&gt;(limits[[&lt;span class=&quot;dv&quot;&gt;2&lt;/span&gt;]]), &lt;span class=&quot;at&quot;&gt;by=&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;5&lt;/span&gt;)) &lt;span class=&quot;sc&quot;&gt;+&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb7-9&quot;&gt;&lt;a href=&quot;#cb7-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;fu&quot;&gt;labs&lt;/span&gt;(&lt;span class=&quot;at&quot;&gt;x=&lt;/span&gt;&lt;span class=&quot;st&quot;&gt;&amp;quot;seconds&amp;quot;&lt;/span&gt;, &lt;span class=&quot;at&quot;&gt;y=&lt;/span&gt;&lt;span class=&quot;st&quot;&gt;&amp;quot;MB&amp;quot;&lt;/span&gt;, &lt;span class=&quot;at&quot;&gt;color =&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;quot;Cost center&amp;quot;&lt;/span&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;figure&gt;
&lt;img src=&quot;/img/heap-profile-ggplot-lines-random-offset.svg&quot;
alt=&quot;A line graph of the heap profile, with a random offset added per cost center&quot; /&gt;
&lt;figcaption aria-hidden=&quot;true&quot;&gt;A line graph of the heap profile, with a
random offset added per cost center&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;So it’s not a glitch, and indeed several cost centers have identical
dynamics. It’s not hard to imagine why this could happen: think about
tuples whose elements occupy the same amount of space but are produced
by different cost centers. As these tuples are consumed and
garbage-collected, the corresponding lines remain in perfect sync. But
this effect wasn’t obvious at all from the stacked plot, was it?&lt;/p&gt;
&lt;p&gt;Another thing that is hard to understand from a stacked plot is how
different cost centers compare, say, in terms of their maximum resident
size. But in R, we can easily visualize this with a simple bar plot:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb8&quot;&gt;&lt;pre class=&quot;sourceCode r&quot;&gt;&lt;code class=&quot;sourceCode r&quot;&gt;&lt;span id=&quot;cb8-1&quot;&gt;&lt;a href=&quot;#cb8-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;top_entries &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; csv &lt;span class=&quot;sc&quot;&gt;%&amp;gt;%&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb8-2&quot;&gt;&lt;a href=&quot;#cb8-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;fu&quot;&gt;group_by&lt;/span&gt;(name) &lt;span class=&quot;sc&quot;&gt;%&amp;gt;%&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb8-3&quot;&gt;&lt;a href=&quot;#cb8-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;fu&quot;&gt;summarize&lt;/span&gt;(&lt;span class=&quot;at&quot;&gt;max_value =&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;max&lt;/span&gt;(value)) &lt;span class=&quot;sc&quot;&gt;%&amp;gt;%&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb8-4&quot;&gt;&lt;a href=&quot;#cb8-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;fu&quot;&gt;filter&lt;/span&gt;(max_value &lt;span class=&quot;sc&quot;&gt;&amp;gt;=&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;) &lt;span class=&quot;sc&quot;&gt;%&amp;gt;%&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb8-5&quot;&gt;&lt;a href=&quot;#cb8-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;fu&quot;&gt;arrange&lt;/span&gt;(max_value) &lt;span class=&quot;sc&quot;&gt;%&amp;gt;%&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb8-6&quot;&gt;&lt;a href=&quot;#cb8-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;fu&quot;&gt;mutate&lt;/span&gt;(&lt;span class=&quot;at&quot;&gt;name =&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;str_trunc&lt;/span&gt;(name, &lt;span class=&quot;dv&quot;&gt;120&lt;/span&gt;), &lt;span class=&quot;at&quot;&gt;name =&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;factor&lt;/span&gt;(name, &lt;span class=&quot;at&quot;&gt;levels=&lt;/span&gt;name))&lt;/span&gt;
&lt;span id=&quot;cb8-7&quot;&gt;&lt;a href=&quot;#cb8-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;fu&quot;&gt;ggplot&lt;/span&gt;(top_entries, &lt;span class=&quot;fu&quot;&gt;aes&lt;/span&gt;(name,max_value)) &lt;span class=&quot;sc&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;geom_col&lt;/span&gt;(&lt;span class=&quot;at&quot;&gt;fill=&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;viridis_pal&lt;/span&gt;(&lt;span class=&quot;at&quot;&gt;alpha=&lt;/span&gt;&lt;span class=&quot;fl&quot;&gt;0.7&lt;/span&gt;)(&lt;span class=&quot;dv&quot;&gt;5&lt;/span&gt;)[[&lt;span class=&quot;dv&quot;&gt;4&lt;/span&gt;]]) &lt;span class=&quot;sc&quot;&gt;+&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb8-8&quot;&gt;&lt;a href=&quot;#cb8-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;fu&quot;&gt;geom_text&lt;/span&gt;(&lt;span class=&quot;fu&quot;&gt;aes&lt;/span&gt;(name,&lt;span class=&quot;at&quot;&gt;label=&lt;/span&gt;name),&lt;span class=&quot;at&quot;&gt;y=&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;0&lt;/span&gt;,&lt;span class=&quot;at&quot;&gt;hjust=&lt;/span&gt;&lt;span class=&quot;st&quot;&gt;&amp;quot;left&amp;quot;&lt;/span&gt;) &lt;span class=&quot;sc&quot;&gt;+&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb8-9&quot;&gt;&lt;a href=&quot;#cb8-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;fu&quot;&gt;labs&lt;/span&gt;(&lt;span class=&quot;at&quot;&gt;x=&lt;/span&gt;&lt;span class=&quot;st&quot;&gt;&amp;quot;Cost center&amp;quot;&lt;/span&gt;, &lt;span class=&quot;at&quot;&gt;y=&lt;/span&gt;&lt;span class=&quot;st&quot;&gt;&amp;quot;Memory, MB&amp;quot;&lt;/span&gt;) &lt;span class=&quot;sc&quot;&gt;+&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb8-10&quot;&gt;&lt;a href=&quot;#cb8-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;fu&quot;&gt;scale_x_discrete&lt;/span&gt;(&lt;span class=&quot;at&quot;&gt;breaks=&lt;/span&gt;&lt;span class=&quot;cn&quot;&gt;NULL&lt;/span&gt;) &lt;span class=&quot;sc&quot;&gt;+&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb8-11&quot;&gt;&lt;a href=&quot;#cb8-11&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;fu&quot;&gt;scale_y_continuous&lt;/span&gt;(&lt;span class=&quot;at&quot;&gt;breaks=&lt;/span&gt;&lt;span class=&quot;cf&quot;&gt;function&lt;/span&gt;(limits) &lt;span class=&quot;fu&quot;&gt;seq&lt;/span&gt;(&lt;span class=&quot;dv&quot;&gt;0&lt;/span&gt;, &lt;span class=&quot;fu&quot;&gt;floor&lt;/span&gt;(limits[[&lt;span class=&quot;dv&quot;&gt;2&lt;/span&gt;]]), &lt;span class=&quot;at&quot;&gt;by=&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;5&lt;/span&gt;)) &lt;span class=&quot;sc&quot;&gt;+&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb8-12&quot;&gt;&lt;a href=&quot;#cb8-12&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;fu&quot;&gt;coord_flip&lt;/span&gt;()&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;figure&gt;
&lt;img src=&quot;/img/heap-profile-ggplot-barplot.svg&quot;
alt=&quot;A bar plot of the maximum residenct size per cost center&quot; /&gt;
&lt;figcaption aria-hidden=&quot;true&quot;&gt;A bar plot of the maximum residenct size
per cost center&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Finally, in R you are not limited to just visualization; you can do
all sorts of data analyses. For instance, a few years back I needed to
verify that, in a server process, a certain function was not consuming
increasingly more memory over time. I used this technique to load the
heap profile into R and verify that with more confidence that I would
have had from looking at a stacked graph.&lt;/p&gt;
&lt;h2 id=&quot;hp2any&quot;&gt;hp2any&lt;/h2&gt;
&lt;p&gt;One issue with big Haskell projects is that, if not actively
maintained, they tend to bitrot due to the changes in the compiler, the
Haskell dependencies or even the C dependencies.&lt;/p&gt;
&lt;p&gt;One such example is Patai Gergely’s &lt;a
href=&quot;https://github.com/cobbpg/hp2any&quot;&gt;hp2any&lt;/a&gt;. It no longer builds
with the current version of the &lt;code&gt;network&lt;/code&gt; package because of
some API changes. But even when I tried to build it with the included
&lt;code&gt;stack.yaml&lt;/code&gt; file, I got&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;glib          &amp;gt; Linking /tmp/stack214336/glib-0.13.6.0/.stack-work/dist/x86_64-linux-tinfo6/Cabal-2.2.0.1/setup/setup ...
glib          &amp;gt; Configuring glib-0.13.6.0...
glib          &amp;gt; build
glib          &amp;gt; Preprocessing library for glib-0.13.6.0..
glib          &amp;gt; setup: Error in C header file.
glib          &amp;gt;   
glib          &amp;gt; /usr/include/glib-2.0/glib/gspawn.h:76: (column 22) [FATAL] 
glib          &amp;gt;   &amp;gt;&amp;gt;&amp;gt; Syntax error!
glib          &amp;gt;   The symbol `__attribute__&amp;#39; does not fit here.
glib          &amp;gt;   &lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I’m guessing (only guessing) that this issue is fixed in the latest
versions of the glib Haskell package, but we can’t benefit from that
when using an old &lt;code&gt;stack.yaml&lt;/code&gt;. This also shows a flaw in
some people’s argument that if you put prospective upper bounds on your
Haskell dependencies, your projects will build forever.&lt;/p&gt;
&lt;p&gt;(At this point, someone will surely mention nix and how it would’ve
helped here. It probably would, but as an owner of a 50GB /nix
directory, I’m not so enthusiastic about adding another 5GB there
consisting of old OpenGL and GTK libraries just to get a heap profile
visualizer.)&lt;/p&gt;
</description>
                        <pubDate>Thu, 14 May 2020 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2020-05-14-visualize-haskell-heap-profiles</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2020-05-14-visualize-haskell-heap-profiles.html</guid>
                </item>
        
                <item>
                        <title>Compile and link a Haskell package against a local C library</title>
                        <description>&lt;p&gt;Let’s say you want to build a Haskell package with a locally built
version of a C library for testing/debugging purposes. Doing this is
easy once you know the right option names, but finding this information
took me some time, so I’m recording it here for the reference.&lt;/p&gt;
&lt;p&gt;Let’s say the headers of your local library are in
&lt;code&gt;/home/user/src/mylib/include&lt;/code&gt; and the library files
(&lt;code&gt;*.so&lt;/code&gt; or &lt;code&gt;*.a&lt;/code&gt;) are in
&lt;code&gt;/home/user/src/mylib/lib&lt;/code&gt;. Then you can put the following
into your &lt;code&gt;stack.yaml&lt;/code&gt; (tested with stack v2.2.0;
instructions for cabal-install should be similar):&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb1&quot;&gt;&lt;pre
class=&quot;sourceCode yaml&quot;&gt;&lt;code class=&quot;sourceCode yaml&quot;&gt;&lt;span id=&quot;cb1-1&quot;&gt;&lt;a href=&quot;#cb1-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;fu&quot;&gt;extra-include-dirs&lt;/span&gt;&lt;span class=&quot;kw&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-2&quot;&gt;&lt;a href=&quot;#cb1-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;at&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;kw&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;at&quot;&gt; /home/user/src/mylib/include&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-3&quot;&gt;&lt;a href=&quot;#cb1-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;fu&quot;&gt;extra-lib-dirs&lt;/span&gt;&lt;span class=&quot;kw&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-4&quot;&gt;&lt;a href=&quot;#cb1-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;at&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;kw&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;at&quot;&gt; /home/user/src/mylib/lib&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-5&quot;&gt;&lt;a href=&quot;#cb1-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;fu&quot;&gt;ghc-options&lt;/span&gt;&lt;span class=&quot;kw&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-6&quot;&gt;&lt;a href=&quot;#cb1-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;at&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;&amp;quot;$locals&amp;quot;&lt;/span&gt;&lt;span class=&quot;kw&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;at&quot;&gt; -optl=-Wl,-rpath,/home/user/src/mylib/lib&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Here &lt;code&gt;&quot;$locals&quot;&lt;/code&gt; means &lt;a
href=&quot;https://docs.haskellstack.org/en/stable/yaml_configuration/#ghc-options&quot;&gt;“apply
the options to all local packages”&lt;/a&gt;.&lt;/p&gt;
</description>
                        <pubDate>Tue, 07 Apr 2020 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2020-04-07-haskell-local-c-library</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2020-04-07-haskell-local-c-library.html</guid>
                </item>
        
                <item>
                        <title>Binomial coefficients via integer division</title>
                        <description>&lt;p&gt;Daniel Lemire &lt;a
href=&quot;https://lemire.me/blog/2020/02/26/fast-divisionless-computation-of-binomial-coefficients/&quot;&gt;explains&lt;/a&gt;
how to compute binomial coefficients using only integer multiplications.
The binomial coefficient &lt;span class=&quot;math inline&quot;&gt;\(n \choose
k\)&lt;/span&gt; is defined as&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;math display&quot;&gt;\[
{n \choose k} = \frac{n!}{k! (n-k)!} = \frac{n(n-1)\cdots(n-k+1)}{1\cdot
2\cdots k}.
\]&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Daniel’s strategy of computing binomial coefficients consists of two
steps.&lt;/p&gt;
&lt;p&gt;First, he expresses the binomial coefficient as an iterative
computation&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;math display&quot;&gt;\[
\begin{align}
a_1 &amp;amp;= n - k + 1 \\
a_z &amp;amp;= \frac{a_{z-1}
(n-k+z)}{z}\label{ii}\hspace{2em}(z=2,\ldots,k)\\
{n \choose k} &amp;amp;= a_k\label{iii}
\end{align}
\]&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Then he replaces integer division in &lt;span
class=&quot;math inline&quot;&gt;\(\eqref{ii}\)&lt;/span&gt; with integer multiplication,
following the &lt;a
href=&quot;https://arxiv.org/abs/1902.01961&quot;&gt;Granlund-Montgomery-Warren
algorithm&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;What wasn’t immediately obvious to me is why we can treat the
division in &lt;span class=&quot;math inline&quot;&gt;\(\eqref{ii}\)&lt;/span&gt; as integer
division in the first place. Indeed, the equality &lt;span
class=&quot;math inline&quot;&gt;\({n \choose k} = a_k\)&lt;/span&gt; obviously holds if we
treat division in &lt;span class=&quot;math inline&quot;&gt;\(\eqref{ii}\)&lt;/span&gt; as
exact rational division. But what happens if we replace it with integer
division, throwing away the fractional part at each iteration? Then we
might potentially arrive at the wrong answer at the end.&lt;/p&gt;
&lt;p&gt;However, it turns out that there never is a fractional part in &lt;span
class=&quot;math inline&quot;&gt;\(\eqref{ii}\)&lt;/span&gt;: all &lt;span
class=&quot;math inline&quot;&gt;\(a_k\)&lt;/span&gt; are integers even if we interpret the
division as a proper (not truncated or rounded) division of rational
numbers.&lt;/p&gt;
&lt;p&gt;To see that, expand the definition of &lt;span
class=&quot;math inline&quot;&gt;\(a_z\)&lt;/span&gt;:&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;math display&quot;&gt;\[
\begin{equation}
\begin{aligned}
a_z &amp;amp;= \frac{a_{z-1} (n-k+z)}{z}\\
&amp;amp;= \frac{a_{z-2} (n-k+z)(n-k+z-1)}{z(z-1)}\\
&amp;amp;= \ldots \\
&amp;amp;= \frac{(n-k+z)(n-k+z-1)\cdots (n-k+1)}{z(z-1)\cdots 1} \\
&amp;amp;= {n-k+z \choose z}.
\end{aligned}\label{expanded}
\end{equation}
\]&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;It turns out that the thing computed at each step of Daniel’s
iterative algorithm is itself a binomial coefficient, and is therefore
an integer. Notice how &lt;span
class=&quot;math inline&quot;&gt;\(\eqref{expanded}\)&lt;/span&gt; reduces to &lt;span
class=&quot;math inline&quot;&gt;\(\eqref{iii}\)&lt;/span&gt; if we let &lt;span
class=&quot;math inline&quot;&gt;\(z = k\)&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;Equation &lt;span class=&quot;math inline&quot;&gt;\(\eqref{ii}\)&lt;/span&gt; can also be
written as&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;math display&quot;&gt;\[
{n-k+z \choose z} = {n-k+z-1 \choose z-1}\cdot \frac{n-k+z}z,
\]&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;which is an instance of the general identity&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;math display&quot;&gt;\[
{p \choose q} = {p-1\choose q-1}\cdot \frac{p}{q}.
\]&lt;/span&gt;&lt;/p&gt;
</description>
                        <pubDate>Sun, 22 Mar 2020 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2020-03-22-binomial-coefficients-integer-division</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2020-03-22-binomial-coefficients-integer-division.html</guid>
                </item>
        
                <item>
                        <title>Does micro-USB cable affect charging speed?</title>
                        <description>&lt;p&gt;How much does a micro-USB cable affect the charging speed of your
phone? Should you pay extra for a premium-quality cable? To find this
out, I ran a small experiment.&lt;/p&gt;
&lt;figure&gt;
&lt;img src=&quot;/img/charging-speed/setup.jpeg&quot;
alt=&quot;The experimental setup&quot; /&gt;
&lt;figcaption aria-hidden=&quot;true&quot;&gt;The experimental setup&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;For this experiment, I tried all combinations of four micro-USB
cables I had lying around, two USB chargers, and three devices to be
charged: a Sony smartphone running Android, a Samsung tablet also
running Android, and a Mimacro power bank. As a proxy for charging
speed, I used the power drawn by the charger measured by a Kill A
Watt-like electricity monitor. To avoid batch effects, I tested
combinations in a pre-determined random order.&lt;/p&gt;
&lt;p&gt;It turns out that I had one particularly bad cable (“Cable 1”) that
was 3-4 times less efficient at charging:&lt;/p&gt;
&lt;figure&gt;
&lt;img src=&quot;/img/charging-speed/by_cable.svg&quot; alt=&quot;Wattage by cable&quot; /&gt;
&lt;figcaption aria-hidden=&quot;true&quot;&gt;Wattage by cable&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;I do not remember how I got Cable 1—whether I bought it separately or
it was included with some gadget—but superficially it looks better built
than some of the other cables, so I was surprised by this result.&lt;/p&gt;
&lt;p&gt;Other than that one cable, all cables were performing similarly,
drawing around 9–11 watts, which at 5V corresponds to the current of
1.8–2.2A.&lt;/p&gt;
&lt;p&gt;There also were no practically significant differences between
different devices or chargers as the graphs below show (where Cable 1
measurements are excluded):&lt;/p&gt;
&lt;figure&gt;
&lt;img src=&quot;/img/charging-speed/by_charger.svg&quot;
alt=&quot;Wattage by charger&quot; /&gt;
&lt;figcaption aria-hidden=&quot;true&quot;&gt;Wattage by charger&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
&lt;img src=&quot;/img/charging-speed/by_consumer.svg&quot;
alt=&quot;Wattage by device being charged&quot; /&gt;
&lt;figcaption aria-hidden=&quot;true&quot;&gt;Wattage by device being
charged&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;None of my devices are new, and none of my cables are particularly
high-end, so your mileage may vary. But my conclusions from this
are:&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;Do not buy the cheapest cable or charger, but it’s not worth
investing extra either.&lt;/li&gt;
&lt;li&gt;Do a quick test to see whether the cable/charger is drawing around
10W or 5A of electricity—do not rely on the “high-quality” look of
it.&lt;/li&gt;
&lt;/ol&gt;
</description>
                        <pubDate>Sun, 08 Mar 2020 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2020-03-08-microusb-charging-speed</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2020-03-08-microusb-charging-speed.html</guid>
                </item>
        
                <item>
                        <title>Break on NaN in gdb</title>
                        <description>&lt;p&gt;Recently I had to debug a case where, somewhere during a
numerically-intensive computation (solving an ordinary differential
equation), a value would become &lt;code&gt;NaN&lt;/code&gt; (“not a number”). This
happens, for example, when taking a logarithm or a square root of a
negative number, dividing 0 by 0, stuff like that. However, I had no
idea where and why NaNs appeared in this particular program.&lt;/p&gt;
&lt;p&gt;So here I’ll show how to detect this using gdb, the GNU debugger.
Here is the program that we will be debugging:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb1&quot;&gt;&lt;pre class=&quot;sourceCode c&quot;&gt;&lt;code class=&quot;sourceCode c&quot;&gt;&lt;span id=&quot;cb1-1&quot;&gt;&lt;a href=&quot;#cb1-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;co&quot;&gt;/* nan.c */&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-2&quot;&gt;&lt;a href=&quot;#cb1-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;pp&quot;&gt;#include &lt;/span&gt;&lt;span class=&quot;im&quot;&gt;&amp;lt;math.h&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-3&quot;&gt;&lt;a href=&quot;#cb1-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;pp&quot;&gt;#include &lt;/span&gt;&lt;span class=&quot;im&quot;&gt;&amp;lt;stdio.h&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-4&quot;&gt;&lt;a href=&quot;#cb1-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;pp&quot;&gt;#include &lt;/span&gt;&lt;span class=&quot;im&quot;&gt;&amp;lt;stdlib.h&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-5&quot;&gt;&lt;a href=&quot;#cb1-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-6&quot;&gt;&lt;a href=&quot;#cb1-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;dt&quot;&gt;void&lt;/span&gt; f1&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dt&quot;&gt;double&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;*&lt;/span&gt;y&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-7&quot;&gt;&lt;a href=&quot;#cb1-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;op&quot;&gt;*&lt;/span&gt;y &lt;span class=&quot;op&quot;&gt;-=&lt;/span&gt; &lt;span class=&quot;fl&quot;&gt;2.0&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-8&quot;&gt;&lt;a href=&quot;#cb1-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-9&quot;&gt;&lt;a href=&quot;#cb1-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-10&quot;&gt;&lt;a href=&quot;#cb1-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;dt&quot;&gt;void&lt;/span&gt; f2&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dt&quot;&gt;double&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;*&lt;/span&gt;z&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-11&quot;&gt;&lt;a href=&quot;#cb1-11&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;op&quot;&gt;*&lt;/span&gt;z &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; sqrt&lt;span class=&quot;op&quot;&gt;(*&lt;/span&gt;z&lt;span class=&quot;op&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-12&quot;&gt;&lt;a href=&quot;#cb1-12&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;op&quot;&gt;*&lt;/span&gt;z &lt;span class=&quot;op&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;fl&quot;&gt;1.0&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-13&quot;&gt;&lt;a href=&quot;#cb1-13&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-14&quot;&gt;&lt;a href=&quot;#cb1-14&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-15&quot;&gt;&lt;a href=&quot;#cb1-15&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;dt&quot;&gt;int&lt;/span&gt; main&lt;span class=&quot;op&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-16&quot;&gt;&lt;a href=&quot;#cb1-16&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;dt&quot;&gt;double&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;*&lt;/span&gt;x &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; malloc&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kw&quot;&gt;sizeof&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dt&quot;&gt;double&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;));&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-17&quot;&gt;&lt;a href=&quot;#cb1-17&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;op&quot;&gt;*&lt;/span&gt;x &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;fl&quot;&gt;5e4&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-18&quot;&gt;&lt;a href=&quot;#cb1-18&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;dt&quot;&gt;int&lt;/span&gt; i&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-19&quot;&gt;&lt;a href=&quot;#cb1-19&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;cf&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;i &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt; i &lt;span class=&quot;op&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;1000&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt; i&lt;span class=&quot;op&quot;&gt;++)&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-20&quot;&gt;&lt;a href=&quot;#cb1-20&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    f1&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;x&lt;span class=&quot;op&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-21&quot;&gt;&lt;a href=&quot;#cb1-21&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    f2&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;x&lt;span class=&quot;op&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-22&quot;&gt;&lt;a href=&quot;#cb1-22&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-23&quot;&gt;&lt;a href=&quot;#cb1-23&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  printf&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;st&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;sc&quot;&gt;%f\n&lt;/span&gt;&lt;span class=&quot;st&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;*&lt;/span&gt;x&lt;span class=&quot;op&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-24&quot;&gt;&lt;a href=&quot;#cb1-24&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  free&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;x&lt;span class=&quot;op&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-25&quot;&gt;&lt;a href=&quot;#cb1-25&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Compile it with&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;gcc -g -lm -Wall -pedantic -onan nan.c&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;and confirm that it produces a NaN:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% ./nan
-nan&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, start gdb and proceed to the point where the storage for our
&lt;code&gt;double&lt;/code&gt; value is allocated:&lt;/p&gt;
&lt;pre class=&quot;terminal&quot;&gt;
Reading symbols from &lt;font color=&quot;#4E9A06&quot;&gt;./nan&lt;/font&gt;...
(gdb) start
Temporary breakpoint 1 at &lt;font color=&quot;#3465A4&quot;&gt;0x4011cd&lt;/font&gt;: file &lt;font color=&quot;#4E9A06&quot;&gt;nan.c&lt;/font&gt;, line 15.

Temporary breakpoint 1, &lt;font color=&quot;#C4A000&quot;&gt;main&lt;/font&gt; () at &lt;font color=&quot;#4E9A06&quot;&gt;nan.c&lt;/font&gt;:15
15    &lt;font color=&quot;#4E9A06&quot;&gt;double&lt;/font&gt; &lt;font color=&quot;#F73B3B&quot;&gt;*&lt;/font&gt;x &lt;font color=&quot;#F73B3B&quot;&gt;=&lt;/font&gt; &lt;b&gt;malloc&lt;/b&gt;&lt;font color=&quot;#F73B3B&quot;&gt;(&lt;/font&gt;&lt;font color=&quot;#3465A4&quot;&gt;&lt;b&gt;sizeof&lt;/b&gt;&lt;/font&gt;&lt;font color=&quot;#F73B3B&quot;&gt;(&lt;/font&gt;&lt;font color=&quot;#4E9A06&quot;&gt;double&lt;/font&gt;&lt;font color=&quot;#F73B3B&quot;&gt;));&lt;/font&gt;
(gdb) next
16    &lt;font color=&quot;#F73B3B&quot;&gt;*&lt;/font&gt;x &lt;font color=&quot;#F73B3B&quot;&gt;=&lt;/font&gt; &lt;font color=&quot;#75507B&quot;&gt;5e4&lt;/font&gt;&lt;font color=&quot;#F73B3B&quot;&gt;;&lt;/font&gt;
&lt;/pre&gt;
&lt;p&gt;At this point we can do two useful things.&lt;/p&gt;
&lt;p&gt;First, we turn on the program execution log, so that we can go back
in time once we encounter a NaN.&lt;/p&gt;
&lt;pre class=&quot;terminal&quot;&gt;(gdb) set record full stop-at-limit off
(gdb) record full
&lt;/pre&gt;
&lt;p&gt;Second, we set a watchpoint that will trigger once &lt;code&gt;*x&lt;/code&gt;
becomes NaN. But how do we express that?&lt;/p&gt;
&lt;p&gt;If we were programming in C, we would use the &lt;code&gt;isnan()&lt;/code&gt;
function. But &lt;code&gt;isnan()&lt;/code&gt; is not a C function, it is a
preprocessor macro and is by default not available in gdb. And even if I
make it available (by compiling the program with &lt;code&gt;-g3&lt;/code&gt;), it
still doesn’t work, at least on my system:&lt;/p&gt;
&lt;pre class=&quot;terminal&quot;&gt;(gdb) macro expand isnan(1.0)
expands to: __builtin_isnan (1.0)
(gdb) print isnan(1.0)
No symbol &amp;quot;__builtin_isnan&amp;quot; in current context.
&lt;/pre&gt;
&lt;p&gt;Luckily, there are a few workarounds. Perhaps the simplest and the
most reliable one is to exploit the fact that NaN is the only
floating-point value not equal to itself. Therefore we can set a
conditional watchpoint like this:&lt;/p&gt;
&lt;pre class=&quot;terminal&quot;&gt;(gdb) watch *x if *x != *x
Hardware watchpoint 2: *x
&lt;/pre&gt;
&lt;p&gt;Some other options are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Figure out the underlying C function used to implement the
&lt;code&gt;isnan&lt;/code&gt; macro. On my system, this seems to work:&lt;/p&gt;
&lt;pre class=&quot;terminal&quot;&gt;(gdb) p ((int (*)(double))__isnan)(sqrt(-1.0))
$1 = 1
(gdb) p ((int (*)(double))__isnan)(sqrt(1.0))
$2 = 0
&lt;/pre&gt;
&lt;p&gt;However, it may differ on your system/compiler/standard
library.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Wrap the standard &lt;code&gt;isnan&lt;/code&gt; macro in a C function in
your program to make it available inside gdb:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb4&quot;&gt;&lt;pre class=&quot;sourceCode c&quot;&gt;&lt;code class=&quot;sourceCode c&quot;&gt;&lt;span id=&quot;cb4-1&quot;&gt;&lt;a href=&quot;#cb4-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;dt&quot;&gt;int&lt;/span&gt; myisnan&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dt&quot;&gt;double&lt;/span&gt; x&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-2&quot;&gt;&lt;a href=&quot;#cb4-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;cf&quot;&gt;return&lt;/span&gt; isnan&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;x&lt;span class=&quot;op&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-3&quot;&gt;&lt;a href=&quot;#cb4-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;(Naming your wrapper function &lt;code&gt;isnan&lt;/code&gt; might work too. In
particular, it doesn’t necessarily lead to an infinite recursion because
the inner &lt;code&gt;isnan&lt;/code&gt; call will be expanded by the preprocessor.
However, the C standard explicitly says (section 7.1.3) that the
standard macro names are reserved identifiers, and redefining these
identifiers results in undefined behavior.)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You can try to inspect the bit pattern of the floating-point
number directly. See e.g. &lt;a
href=&quot;https://lists.gnu.org/archive/html/help-gplusplus/2006-07/msg00006.html&quot;&gt;this
answer by Paul Pluzhnikov&lt;/a&gt;. Note, however, that IEEE 754 NaNs do not
have a fixed bit pattern as Paul appears to assume (they may have an
arbitrary fraction part), so unless you know exactly what NaN you are
expecting, you have to be more careful.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In any case, once we’ve started recording the execution log and set a
watchpoint, we are ready to restart the program and wait for the
condition to trigger:&lt;/p&gt;
&lt;pre class=&quot;terminal&quot;&gt;(gdb) continue
Continuing.

Hardware watchpoint 2: *x

Old value = -0.19219211672498604
New value = -nan(0x8000000000000)
&lt;font color=&quot;#C4A000&quot;&gt;f2&lt;/font&gt; (&lt;font color=&quot;#06989A&quot;&gt;z&lt;/font&gt;=0x4052a0) at &lt;font color=&quot;#4E9A06&quot;&gt;nan.c&lt;/font&gt;:11
11    &lt;font color=&quot;#F73B3B&quot;&gt;*&lt;/font&gt;z &lt;font color=&quot;#F73B3B&quot;&gt;+=&lt;/font&gt; &lt;font color=&quot;#75507B&quot;&gt;1.0&lt;/font&gt;&lt;font color=&quot;#F73B3B&quot;&gt;;&lt;/font&gt;
&lt;/pre&gt;
&lt;p&gt;Now we know that NaN was produced in &lt;code&gt;f2&lt;/code&gt; right before
line 11. If this is not enough to diagnose the bug, we can use the
execution log to go back in time. Let’s say we want to find out what the
value of &lt;code&gt;*x&lt;/code&gt; was before the last &lt;code&gt;f1&lt;/code&gt; call.&lt;/p&gt;
&lt;pre class=&quot;terminal&quot;&gt;(gdb) tbreak f1
Temporary breakpoint 3 at &lt;font color=&quot;#3465A4&quot;&gt;0x40115e&lt;/font&gt;: file &lt;font color=&quot;#4E9A06&quot;&gt;nan.c&lt;/font&gt;, line 6.
(gdb) reverse-continue
Continuing.

Temporary breakpoint 3, &lt;font color=&quot;#C4A000&quot;&gt;f1&lt;/font&gt; (&lt;font color=&quot;#06989A&quot;&gt;y&lt;/font&gt;=0x4052a0) at &lt;font color=&quot;#4E9A06&quot;&gt;nan.c&lt;/font&gt;:6
6     &lt;font color=&quot;#F73B3B&quot;&gt;*&lt;/font&gt;y &lt;font color=&quot;#F73B3B&quot;&gt;-=&lt;/font&gt; &lt;font color=&quot;#75507B&quot;&gt;2.0&lt;/font&gt;&lt;font color=&quot;#F73B3B&quot;&gt;;&lt;/font&gt;
(gdb) print *y
$1 = 1.807807883275014
&lt;/pre&gt;
</description>
                        <pubDate>Sat, 11 Jan 2020 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2020-01-11-gdb-break-on-nan</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2020-01-11-gdb-break-on-nan.html</guid>
                </item>
        
                <item>
                        <title>Significance level vs. the type I error chance, or how to interpret conditionals</title>
                        <description>&lt;p&gt;One of the &lt;a
href=&quot;http://www.perfendo.org/docs/BayesProbability/twelvePvaluemisconceptions.pdf&quot;&gt;12
p-value misconceptions&lt;/a&gt; states:&lt;/p&gt;
&lt;blockquote&gt;
&lt;ol start=&quot;10&quot; type=&quot;1&quot;&gt;
&lt;li&gt;With a &lt;span class=&quot;math inline&quot;&gt;\(P = .05\)&lt;/span&gt; threshold for
significance, the chance of a type I error will be 5%.&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;
&lt;p&gt;I find this to be a particularly counter-intuitive one. Recall that
the type I error occurs when we reject the null hypothesis if the null
hypothesis is in fact true. Therefore, the chance of committing a type I
error is &lt;span class=&quot;math inline&quot;&gt;\(p(\text{reject } H_0 |
H_0\text{ is true})\)&lt;/span&gt;—which is exactly the definition of the
significance level!&lt;/p&gt;
&lt;p&gt;The confusion here stems from the ill-defined mapping from the
English language to the language of the probability theory. Consider
these semantically equivalent ways to state when a type I error
occurs:&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;Type I error occurs when we reject &lt;span
class=&quot;math inline&quot;&gt;\(H_0\)&lt;/span&gt;, given that &lt;span
class=&quot;math inline&quot;&gt;\(H_0\)&lt;/span&gt; is true.&lt;/li&gt;
&lt;li&gt;Type I error occurs when &lt;span class=&quot;math inline&quot;&gt;\(H_0\)&lt;/span&gt; is
true, given that we have rejected it.&lt;/li&gt;
&lt;li&gt;Type I error occurs when &lt;span class=&quot;math inline&quot;&gt;\(H_0\)&lt;/span&gt; is
true and we reject it.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;If we try to map these descriptions to their probabilities by
replacing “given” with the conditional probability “|”, we will get
three distinct probabilities:&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;&lt;span class=&quot;math inline&quot;&gt;\(p(\text{reject } H_0 | H_0\text{ is
true})\)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span class=&quot;math inline&quot;&gt;\(p(H_0\text{ is true} | \text{reject }
H_0)\)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span class=&quot;math inline&quot;&gt;\(p(H_0\text{ is true} \wedge \text{reject
} H_0)\)&lt;/span&gt;, where &lt;span class=&quot;math inline&quot;&gt;\(\wedge\)&lt;/span&gt; means
the logical “and”.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;However, in this particular case there is no ambiguity. This is
because a “type I error” is an event (whose probability is the subject
of the misconception), but &lt;span class=&quot;math inline&quot;&gt;\(\text{reject }
H_0 | H_0\text{ is true}\)&lt;/span&gt; and &lt;span
class=&quot;math inline&quot;&gt;\(H_0\text{ is true} | \text{reject } H_0\)&lt;/span&gt;
are &lt;em&gt;not&lt;/em&gt; events. (You can find a proof that “|” cannot be an
operator constructing new propositions/events in Richard Jeffrey’s
“Subjective Probability: The Real Thing”, section 1.5.)&lt;/p&gt;
&lt;p&gt;Therefore, the only possible interpretation is the third one.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;Here’s another scenario where interpreting conditionals may be
ambiguous. You say “I bet you that if Bernie Sanders becomes the
Democratic candidate in the 2020 election, he’ll defeat his opponent”. I
take the bet, and we each put $10 on the respective outcomes. Now
imagine Sanders &lt;em&gt;does not&lt;/em&gt; win the Democratic primaries. Who wins
the $10?&lt;/p&gt;
&lt;p&gt;One way to resolve this is to say that our whole bet was conditional
on Sanders becoming the Democratic nominee in 2020. Since he didn’t, the
bet is called off and no one pays. Under this interpretation, the
probability of you winning the bet is&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;math display&quot;&gt;\[p(\text{Sanders becomes president } |
\text{ Sanders is nominated for president}).\]&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;The fact that we had to recall the bet remidns us that this a
&lt;em&gt;conditional probability&lt;/em&gt;, and is not an unconditional
probability of the “event”&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;math display&quot;&gt;\[\text{Sanders becomes president } |
\text{ Sanders is nominated for president}.\]&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Alternatively, you could say you were proven correct. Your statement
essentially was&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;math display&quot;&gt;\[\text{Sanders is nominated for president
} \Rightarrow \text{ Sanders becomes
president}.\]&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Since the antecedent is false (Sanders was not nominated), the rules
of logic say that the whole implication is true. And since I took the
other side of the bet, essentially betting on you being wrong, I
lost.&lt;/p&gt;
&lt;p&gt;The probability of you winning the bet under such an interpretation
is&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;math display&quot;&gt;\[p(\neg\text{(Sanders is nominated for
president) } \vee \text{ Sanders becomes
president}),\]&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;(where &lt;span class=&quot;math inline&quot;&gt;\(\neg\)&lt;/span&gt; and &lt;span
class=&quot;math inline&quot;&gt;\(\vee\)&lt;/span&gt; mean the logical “not” and “or”,
respectively) because only in the case when Sanders is nominated but
loses the election can I claim that your statement was wrong.&lt;/p&gt;
</description>
                        <pubDate>Sat, 21 Dec 2019 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2019-12-21-significance-level</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2019-12-21-significance-level.html</guid>
                </item>
        
                <item>
                        <title>Bioinformatics events in Europe in 2020</title>
                        <description>&lt;p&gt;Here are some conferences and summer schools that will take place in
Europe in 2020 and may be of interest to fellow bioinformaticians.&lt;/p&gt;
&lt;p&gt;Previous editions: &lt;a
href=&quot;/articles/2017-12-27-europe-bioinformatics-events-2018&quot;&gt;2018&lt;/a&gt;,
&lt;a
href=&quot;/articles/2018-12-06-europe-bioinformatics-events-2019&quot;&gt;2019&lt;/a&gt;.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;
Event
&lt;/th&gt;
&lt;th&gt;
Dates
&lt;/th&gt;
&lt;th&gt;
Location
&lt;/th&gt;
&lt;th&gt;
Early registration price
&lt;/th&gt;
&lt;th&gt;
Early registration deadline
&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;a href=&quot;https://dsb-meeting.github.io/DSB2020/&quot;&gt;Data Structures in
Bioinformatics&lt;/a&gt;
&lt;/td&gt;
&lt;td&gt;
February 3–5
&lt;/td&gt;
&lt;td&gt;
Rennes, France
&lt;/td&gt;
&lt;td&gt;
Free
&lt;/td&gt;
&lt;td&gt;
January 20
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;a href=&quot;https://www.woodstock.bio/&quot;&gt;Woodstock.Bio&lt;/a&gt;
&lt;/td&gt;
&lt;td&gt;
February 13–14
&lt;/td&gt;
&lt;td&gt;
Tel-Aviv, Israel
&lt;/td&gt;
&lt;td&gt;
Free
&lt;/td&gt;
&lt;td&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;a
href=&quot;https://www.vibconferences.be/events/applied-bioinformatics-in-life-sciences-3rd-edition&quot;&gt;Applied
Bioinformatics in Life Sciences&lt;/a&gt;
&lt;/td&gt;
&lt;td&gt;
February 13–14
&lt;/td&gt;
&lt;td&gt;
Leuven, Belgium
&lt;/td&gt;
&lt;td&gt;
€500
&lt;/td&gt;
&lt;td&gt;
December 20, 2019
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;a href=&quot;https://manchestermage.wordpress.com/&quot;&gt;Manchester’s Molecular
and Genome Evolution Symposium&lt;/a&gt;
&lt;/td&gt;
&lt;td&gt;
March 20
&lt;/td&gt;
&lt;td&gt;
Manchester, UK
&lt;/td&gt;
&lt;td&gt;
Free
&lt;/td&gt;
&lt;td&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;a href=&quot;https://www.recomb2020.org/&quot;&gt;RECOMB&lt;/a&gt;
&lt;/td&gt;
&lt;td&gt;
May 10–13
&lt;/td&gt;
&lt;td&gt;
Padova, Italy
&lt;/td&gt;
&lt;td&gt;
€855
&lt;/td&gt;
&lt;td&gt;
March 3
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;a href=&quot;https://londoncallingconf.co.uk/&quot;&gt;London Calling&lt;/a&gt;
&lt;/td&gt;
&lt;td&gt;
May 20–22
&lt;/td&gt;
&lt;td&gt;
London, UK
&lt;/td&gt;
&lt;td&gt;
£699 + 20% VAT
&lt;/td&gt;
&lt;td&gt;
February 28
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;a
href=&quot;https://centuri-livingsystems.org/centuri-summer-school-2020/&quot;&gt;CENTURI
Summer School: From data to biology and back&lt;/a&gt;
&lt;/td&gt;
&lt;td&gt;
June 16–25
&lt;/td&gt;
&lt;td&gt;
Marseille, France
&lt;/td&gt;
&lt;td&gt;
€75
&lt;/td&gt;
&lt;td&gt;
May 4
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;a href=&quot;https://ngschool.eu/ngschool2020/&quot;&gt;#NGSchool2020: Statistical
Learning in Genomics&lt;/a&gt;
&lt;/td&gt;
&lt;td&gt;
July 22–31
&lt;/td&gt;
&lt;td&gt;
Białobrzegi, Poland
&lt;/td&gt;
&lt;td&gt;
&lt;/td&gt;
&lt;td&gt;
April 17
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;a href=&quot;https://ngschool.eu/conference/&quot;&gt;NGSymposium in Computational
Biology&lt;/a&gt;
&lt;/td&gt;
&lt;td&gt;
July 31–August 1
&lt;/td&gt;
&lt;td&gt;
Warsaw, Poland
&lt;/td&gt;
&lt;td&gt;
€75
&lt;/td&gt;
&lt;td&gt;
March 27
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;a href=&quot;http://www.popgen.dk/popgen20/&quot;&gt;Summer course in analyses of
genotyping and NGS data in medical and population genetics&lt;/a&gt;
&lt;/td&gt;
&lt;td&gt;
August 3–7
&lt;/td&gt;
&lt;td&gt;
Copenhagen, Denmark
&lt;/td&gt;
&lt;td&gt;
$200
&lt;/td&gt;
&lt;td&gt;
March 30
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;a href=&quot;https://eccb2020.info/&quot;&gt;ECCB&lt;/a&gt;
&lt;/td&gt;
&lt;td&gt;
September 5–9
&lt;/td&gt;
&lt;td&gt;
Sitges, Barcelona, Spain
&lt;/td&gt;
&lt;td&gt;
€775
&lt;/td&gt;
&lt;td&gt;
March 16
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;a href=&quot;http://algo2020.di.unipi.it/WABI2020/&quot;&gt;Workshop on Algorithms
in Bioinformatics (WABI)&lt;/a&gt;
&lt;/td&gt;
&lt;td&gt;
September 7–9
&lt;/td&gt;
&lt;td&gt;
Pisa, Italy
&lt;/td&gt;
&lt;td&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
</description>
                        <pubDate>Sun, 15 Dec 2019 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2019-12-15-europe-bioinformatics-events-2020</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2019-12-15-europe-bioinformatics-events-2020.html</guid>
                </item>
        
                <item>
                        <title>Long-term reminders</title>
                        <description>&lt;p&gt;By long-term reminders I mean things that are not actionable right
now, but at some point in the future become important to take care of:
cancel a subscription or a credit card, renew a passport/visa/driver’s
license etc.&lt;/p&gt;
&lt;p&gt;At one point I used &lt;a
href=&quot;/articles/2018-06-15-encrypted-reminders-nudgemail&quot;&gt;nudgemail&lt;/a&gt;
for this. However, I ran into a pretty serious date parsing/scheduling
bug: I had two reminders, one for October 6 and one for October 20, and
both arrived on October 1. I never received a response to the email I
sent to support@nudgemail.com, so I don’t consider them reliable
anymore.&lt;/p&gt;
&lt;p&gt;That got me thinking: what &lt;em&gt;is&lt;/em&gt; a reliable way to send a
message to the future me?&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Email reminders seem perfect for this, if only there existed a
service that has proved to be dependable (I’m not aware of one).&lt;/li&gt;
&lt;li&gt;Telegram allows to schedule messages in the future and send them to
oneself. But since telegram is tied to my phone number, there is a high
chance that in a year or two I’ll have a different phone number and will
lose my reminder.&lt;/li&gt;
&lt;li&gt;There are probably many mobile apps for this, but then I need to
remember to transfer them to any new phone I may have.&lt;/li&gt;
&lt;li&gt;I considered writing or installing an existing self-hosted email
scheduling solution, but it would become a maintenance burden.&lt;/li&gt;
&lt;li&gt;I also considered doing it UNIX-way, using &lt;code&gt;atd&lt;/code&gt; and
&lt;code&gt;mail&lt;/code&gt;, but:
&lt;ul&gt;
&lt;li&gt;What if I forget to transfer my &lt;code&gt;atd&lt;/code&gt; files to the next
system/device?&lt;/li&gt;
&lt;li&gt;How to ensure reliable delivery of mail from localhost? (I don’t set
up smtpd/smarthosts these days.)&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Here’s what I decided in the end, inspired by the
&lt;code&gt;birthday&lt;/code&gt; program:&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;&lt;p&gt;I write my reminders in a simple text file structured like
this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;YYYY-MM-DD&amp;lt;tab&amp;gt;description&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For instance:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;2021-01-03   Renew ro-che.info&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;I wrote a small Haskell program that parses the file and prints
any reminders that are due.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;I added &lt;code&gt;remind ~/my/reminders.txt&lt;/code&gt; to
&lt;code&gt;~/.zshrc&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;I figured that in several years I’ll still be using terminals and
zsh, and I tend to back up and transfer these files to new systems, so
this is one of the most reliable way to send a message to the future for
me.&lt;/p&gt;
</description>
                        <pubDate>Fri, 22 Nov 2019 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2019-11-22-long-term-reminders</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2019-11-22-long-term-reminders.html</guid>
                </item>
        
                <item>
                        <title>A blind microphone comparison</title>
                        <description>&lt;p&gt;Like many other podcasters, I like obsessing over different
microphones and watching mic reviews. Unfortunately, most of these
reviews are not blind, and so your impression is inevitably affected by
how the microphone looks, what its price is, opinions you’ve heard about
the mic etc.&lt;/p&gt;
&lt;p&gt;So here’s a blind test of the three microphones that I currently own.
Feel free to &lt;a href=&quot;/&quot;&gt;tell me&lt;/a&gt; both your subjective (which one you
liked more) and objective (what type/price range/model you think these
are) thoughts, and I’ll tell you what these microphones are.&lt;/p&gt;
&lt;p&gt;&lt;label for=&quot;275de6e8&quot;&gt;Mic 1&lt;/label&gt;
&lt;audio id=&quot;275de6e8&quot; controls style=&quot;width: 100%;&quot; preload=&quot;metadata&quot;&gt;
&lt;source src=&quot;/files/2019-09-04-blind-mic-comparison/275de6e8.mp3&quot; type=&quot;audio/mp3&quot;&gt;
&lt;/audio&gt; &lt;label for=&quot;2df72bfd&quot;&gt;Mic 2&lt;/label&gt;
&lt;audio id=&quot;2df72bfd&quot; controls style=&quot;width: 100%;&quot; preload=&quot;metadata&quot;&gt;
&lt;source src=&quot;/files/2019-09-04-blind-mic-comparison/2df72bfd.mp3&quot; type=&quot;audio/mp3&quot;&gt;
&lt;/audio&gt; &lt;label for=&quot;7eca74bc&quot;&gt;Mic 3&lt;/label&gt;
&lt;audio id=&quot;7eca74bc&quot; controls style=&quot;width: 100%;&quot; preload=&quot;metadata&quot;&gt;
&lt;source src=&quot;/files/2019-09-04-blind-mic-comparison/7eca74bc.mp3&quot; type=&quot;audio/mp3&quot;&gt;
&lt;/audio&gt;&lt;/p&gt;
&lt;p&gt;Text credit: &lt;a
href=&quot;https://irispublishers.com/sjrr/pdf/SJRR.MS.ID.000540.pdf&quot;&gt;Daniel
T. Baldassarre&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Here are some other blind microphone tests you may enjoy:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a
href=&quot;https://www.youtube.com/watch?v=bk3rOUYiqEo&amp;amp;list=PLpPR2HcQu7YLFvXjkxlm8eTP-CRNbVb_Y&quot;&gt;Masked
mics&lt;/a&gt; series by Allen Williams&lt;/li&gt;
&lt;li&gt;&lt;a
href=&quot;https://podcastengineeringschool.com/8-mic-shootout-with-david-hooper-pes-159/&quot;&gt;8-Mic
Shootout With David Hooper&lt;/a&gt; by Chris Curran&lt;/li&gt;
&lt;/ul&gt;
</description>
                        <pubDate>Wed, 04 Sep 2019 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2019-09-04-blind-mic-comparison</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2019-09-04-blind-mic-comparison.html</guid>
                </item>
        
                <item>
                        <title>A curious associativity of the &lt;$&gt; operator</title>
                        <description>&lt;p&gt;The &lt;code&gt;&amp;lt;$&amp;gt;&lt;/code&gt; operator in Haskell is an infix synonym
for &lt;code&gt;fmap&lt;/code&gt; and has the type&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb1&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb1-1&quot;&gt;&lt;a href=&quot;#cb1-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;(&amp;lt;$&amp;gt;) ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Functor&lt;/span&gt; f &lt;span class=&quot;ot&quot;&gt;=&amp;gt;&lt;/span&gt; (a &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; b) &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; f a &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; f b&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;For example:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb2&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb2-1&quot;&gt;&lt;a href=&quot;#cb2-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;op&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;negate&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;&amp;lt;$&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Just&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;5&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-2&quot;&gt;&lt;a href=&quot;#cb2-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;dt&quot;&gt;Just&lt;/span&gt; (&lt;span class=&quot;op&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;5&lt;/span&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Like all other operators, &lt;code&gt;&amp;lt;$&amp;gt;&lt;/code&gt; has a
&lt;em&gt;fixity&lt;/em&gt;, which can be &lt;code&gt;infixl&lt;/code&gt;, &lt;code&gt;infixr&lt;/code&gt;,
or &lt;code&gt;infix&lt;/code&gt;. The fixity defines how an expression like&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb3&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb3-1&quot;&gt;&lt;a href=&quot;#cb3-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;fu&quot;&gt;abs&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;&amp;lt;$&amp;gt;&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;negate&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;&amp;lt;$&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Just&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;5&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;is parsed.&lt;/p&gt;
&lt;p&gt;If &lt;code&gt;&amp;lt;$&amp;gt;&lt;/code&gt; were defined as &lt;code&gt;infix&lt;/code&gt;, then
the above expression wouldn’t parse at all, giving an error like&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Precedence parsing error
    cannot mix ‘&amp;lt;$&amp;gt;’ [infix 4] and ‘&amp;lt;$&amp;gt;’ [infix 4] in the same infix expression&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If &lt;code&gt;&amp;lt;$&amp;gt;&lt;/code&gt; instead were defined as
&lt;code&gt;infixr&lt;/code&gt;, then the above expression would parse as&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb5&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb5-1&quot;&gt;&lt;a href=&quot;#cb5-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;fu&quot;&gt;abs&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;&amp;lt;$&amp;gt;&lt;/span&gt; (&lt;span class=&quot;fu&quot;&gt;negate&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;&amp;lt;$&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Just&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;5&lt;/span&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;meaning first apply &lt;code&gt;negate&lt;/code&gt; to 5 inside
&lt;code&gt;Just&lt;/code&gt;, and then go inside &lt;code&gt;Just&lt;/code&gt; once more and
apply &lt;code&gt;abs&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;However, &lt;code&gt;&amp;lt;$&amp;gt;&lt;/code&gt; is defined as &lt;code&gt;infixl&lt;/code&gt;, so
that the applicative chains like&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb6&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb6-1&quot;&gt;&lt;a href=&quot;#cb6-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;(&lt;span class=&quot;op&quot;&gt;+&lt;/span&gt;) &lt;span class=&quot;op&quot;&gt;&amp;lt;$&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Just&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;5&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;&amp;lt;*&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Just&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;6&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;would parse correctly. This means that&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb7&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb7-1&quot;&gt;&lt;a href=&quot;#cb7-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;fu&quot;&gt;abs&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;&amp;lt;$&amp;gt;&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;negate&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;&amp;lt;$&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Just&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;5&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;is parsed as&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb8&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb8-1&quot;&gt;&lt;a href=&quot;#cb8-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;(&lt;span class=&quot;fu&quot;&gt;abs&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;&amp;lt;$&amp;gt;&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;negate&lt;/span&gt;) &lt;span class=&quot;op&quot;&gt;&amp;lt;$&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Just&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;5&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;which is probably not what you meant. Or is it?&lt;/p&gt;
&lt;p&gt;It turns out that if you paste that expression (either parenthesized
or not) into ghci, you’ll get back &lt;code&gt;Just 5&lt;/code&gt; in all cases.&lt;/p&gt;
&lt;p&gt;This happens because of the following instance defined in the base
library:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb9&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb9-1&quot;&gt;&lt;a href=&quot;#cb9-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;instance&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Functor&lt;/span&gt; ((&lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt;) r) &lt;span class=&quot;kw&quot;&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb9-2&quot;&gt;&lt;a href=&quot;#cb9-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;fu&quot;&gt;fmap&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; (&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;(Note that &lt;code&gt;(-&amp;gt;) r&lt;/code&gt; is essentially the Reader monad, so
it’s not surprising that it’s a functor.)&lt;/p&gt;
&lt;p&gt;So the expression&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb10&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb10-1&quot;&gt;&lt;a href=&quot;#cb10-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;(&lt;span class=&quot;fu&quot;&gt;abs&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;&amp;lt;$&amp;gt;&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;negate&lt;/span&gt;) &lt;span class=&quot;op&quot;&gt;&amp;lt;$&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Just&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;5&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;does make sense and is equivalent to&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb11&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb11-1&quot;&gt;&lt;a href=&quot;#cb11-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;(&lt;span class=&quot;fu&quot;&gt;abs&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;negate&lt;/span&gt;) &lt;span class=&quot;op&quot;&gt;&amp;lt;$&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Just&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;5&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The operators &lt;code&gt;*&lt;/code&gt; for which
&lt;code&gt;a * (b * c) = (a * b) * c&lt;/code&gt; are called &lt;em&gt;associative&lt;/em&gt;.
Usually associative operators have the type
&lt;code&gt;a -&amp;gt; a -&amp;gt; a&lt;/code&gt; (either polymorphic of for a specific
&lt;code&gt;a&lt;/code&gt;), so that both ways to put parentheses typecheck.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;&amp;lt;$&amp;gt;&lt;/code&gt; operator is curious because it doesn’t
have such a type and yet is associative:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb12&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb12-1&quot;&gt;&lt;a href=&quot;#cb12-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;f &lt;span class=&quot;op&quot;&gt;&amp;lt;$&amp;gt;&lt;/span&gt; (g &lt;span class=&quot;op&quot;&gt;&amp;lt;$&amp;gt;&lt;/span&gt; h) &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb12-2&quot;&gt;&lt;a href=&quot;#cb12-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;co&quot;&gt;{- the definition of &amp;lt;$&amp;gt; -}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb12-3&quot;&gt;&lt;a href=&quot;#cb12-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;fu&quot;&gt;fmap&lt;/span&gt; f (&lt;span class=&quot;fu&quot;&gt;fmap&lt;/span&gt; g h) &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb12-4&quot;&gt;&lt;a href=&quot;#cb12-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;co&quot;&gt;{- the definition of (.) -}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb12-5&quot;&gt;&lt;a href=&quot;#cb12-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;(&lt;span class=&quot;fu&quot;&gt;fmap&lt;/span&gt; f &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;fmap&lt;/span&gt; g) h &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb12-6&quot;&gt;&lt;a href=&quot;#cb12-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;co&quot;&gt;{- the functor law -}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb12-7&quot;&gt;&lt;a href=&quot;#cb12-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;fu&quot;&gt;fmap&lt;/span&gt; (f &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt; g) h &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb12-8&quot;&gt;&lt;a href=&quot;#cb12-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;co&quot;&gt;{- the definition of &amp;lt;$&amp;gt; -}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb12-9&quot;&gt;&lt;a href=&quot;#cb12-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;(f &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt; g) &lt;span class=&quot;op&quot;&gt;&amp;lt;$&amp;gt;&lt;/span&gt; h &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb12-10&quot;&gt;&lt;a href=&quot;#cb12-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;co&quot;&gt;{- the Functor instance for (-&amp;gt;) r -}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb12-11&quot;&gt;&lt;a href=&quot;#cb12-11&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;co&quot;&gt;{- g has to be a function for the top expression to typecheck -}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb12-12&quot;&gt;&lt;a href=&quot;#cb12-12&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;(f &lt;span class=&quot;op&quot;&gt;&amp;lt;$&amp;gt;&lt;/span&gt; g) &lt;span class=&quot;op&quot;&gt;&amp;lt;$&amp;gt;&lt;/span&gt; h&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
</description>
                        <pubDate>Mon, 22 Jul 2019 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2019-07-22-associativity-of-fmap</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2019-07-22-associativity-of-fmap.html</guid>
                </item>
        
                <item>
                        <title>Decompose ContT</title>
                        <description>&lt;p&gt;Can we decompose a ContT action into separate acquire and release
functions?&lt;/p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;/h2&gt;
&lt;p&gt;Consider some resource, such as a file handle, socket, database
connection etc. The two actions common to all resources are acquiring
and releasing.&lt;/p&gt;
&lt;p&gt;There are two ways to represent these actions: as a pair of
functions&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb1&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb1-1&quot;&gt;&lt;a href=&quot;#cb1-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;acquireResource ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;IO&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Resource&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-2&quot;&gt;&lt;a href=&quot;#cb1-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;releaseResource ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Resource&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;IO&lt;/span&gt; ()&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;or as a single function&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb2&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb2-1&quot;&gt;&lt;a href=&quot;#cb2-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;withResource ::&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;Resource&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;IO&lt;/span&gt; a) &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;IO&lt;/span&gt; a&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;As I explained in &lt;a href=&quot;/articles/2019-06-07-why-use-contt&quot;&gt;Why
would you use ContT?&lt;/a&gt;, the latter can be nicely wrapped into a
continuation monad:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb3&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb3-1&quot;&gt;&lt;a href=&quot;#cb3-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;getResource ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;ContT&lt;/span&gt; r &lt;span class=&quot;dt&quot;&gt;IO&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Resource&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-2&quot;&gt;&lt;a href=&quot;#cb3-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;getResource &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;ContT&lt;/span&gt; withResource&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;We can go from an &lt;code&gt;(acquireResource, releaseResource)&lt;/code&gt;
pair to the ContT version by using &lt;code&gt;bracket&lt;/code&gt; from
&lt;code&gt;Control.Exception&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb4&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb4-1&quot;&gt;&lt;a href=&quot;#cb4-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;getResource ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;ContT&lt;/span&gt; r &lt;span class=&quot;dt&quot;&gt;IO&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Resource&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-2&quot;&gt;&lt;a href=&quot;#cb4-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;getResource &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;ContT&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; bracket acquireResource releaseResource&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;But can we go in the opposite direction, i.e. decompose a value of
type &lt;code&gt;ContT r IO Resource&lt;/code&gt; into separate acquire and release
functions?&lt;/p&gt;
&lt;p&gt;To give an example of why we may want to do that, say a library only
provides the &lt;code&gt;withResource&lt;/code&gt; or &lt;code&gt;getResource&lt;/code&gt; form,
but we want to cache the allocated resource instances, deciding
dynamically which ones to free. Another example would be combining
resources and coroutines, see &lt;a
href=&quot;https://www.fpcomplete.com/blog/2017/06/understanding-resourcet&quot;&gt;Understanding
ResourceT&lt;/a&gt; by Michael Snoyman.&lt;/p&gt;
&lt;p&gt;Note that not every &lt;code&gt;ContT&lt;/code&gt; action follows the pattern
“acquire; call the continuation; release”. Instead, the continuation may
be called multiple times like so:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb5&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb5-1&quot;&gt;&lt;a href=&quot;#cb5-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;getInt ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;ContT&lt;/span&gt; r &lt;span class=&quot;dt&quot;&gt;IO&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Int&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-2&quot;&gt;&lt;a href=&quot;#cb5-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;getInt &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;ContT&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; \k &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;last&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;&amp;lt;$&amp;gt;&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;mapM&lt;/span&gt; k [&lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;..&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;5&lt;/span&gt;]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;(The parametricity ensures, however, that an action of type
&lt;code&gt;forall r . ContT r m a&lt;/code&gt; will call its continuation &lt;em&gt;at
least once&lt;/em&gt; or throw an exception.)&lt;/p&gt;
&lt;p&gt;So what we are really asking is, assuming the ContT action has a
certain form such as &lt;code&gt;bracket acquire release&lt;/code&gt;, can we
recover the &lt;code&gt;acquire&lt;/code&gt; and &lt;code&gt;release&lt;/code&gt;&lt;a href=&quot;#fn1&quot;
class=&quot;footnote-ref&quot; id=&quot;fnref1&quot; role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;1&lt;/sup&gt;&lt;/a&gt;
actions?&lt;/p&gt;
&lt;h2 id=&quot;a-beautiful-but-useless-solution&quot;&gt;A beautiful but useless
solution&lt;/h2&gt;
&lt;p&gt;If our ContT action has the form&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb6&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb6-1&quot;&gt;&lt;a href=&quot;#cb6-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;withResource ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;MonadIO&lt;/span&gt; m &lt;span class=&quot;ot&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;ContT&lt;/span&gt; r m &lt;span class=&quot;dt&quot;&gt;Resource&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-2&quot;&gt;&lt;a href=&quot;#cb6-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;withResource &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;ContT&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; \k &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-3&quot;&gt;&lt;a href=&quot;#cb6-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  x &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; acquire&lt;/span&gt;
&lt;span id=&quot;cb6-4&quot;&gt;&lt;a href=&quot;#cb6-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  r &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; k x&lt;/span&gt;
&lt;span id=&quot;cb6-5&quot;&gt;&lt;a href=&quot;#cb6-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  release x&lt;/span&gt;
&lt;span id=&quot;cb6-6&quot;&gt;&lt;a href=&quot;#cb6-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;fu&quot;&gt;return&lt;/span&gt; r&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;then we can recover the &lt;code&gt;acquire&lt;/code&gt; and
&lt;code&gt;release x&lt;/code&gt; actions by… adding another ContT layer! This may
sound bizarre, but the intuition behind this is simple: the
&lt;code&gt;release x&lt;/code&gt; is itself a &lt;em&gt;continuation&lt;/em&gt; of
&lt;code&gt;k x&lt;/code&gt;—it is what happens when &lt;code&gt;k x&lt;/code&gt; returns—and
the ContT monad allows us to capture that continuation. Here’s the
code:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb7&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb7-1&quot;&gt;&lt;a href=&quot;#cb7-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;{-# LANGUAGE RankNTypes, ScopedTypeVariables #-}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb7-2&quot;&gt;&lt;a href=&quot;#cb7-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Control.Monad.Cont&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb7-3&quot;&gt;&lt;a href=&quot;#cb7-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Control.Monad.IO.Class&lt;/span&gt; (liftIO)&lt;/span&gt;
&lt;span id=&quot;cb7-4&quot;&gt;&lt;a href=&quot;#cb7-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb7-5&quot;&gt;&lt;a href=&quot;#cb7-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;runC ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Monad&lt;/span&gt; m &lt;span class=&quot;ot&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;ContT&lt;/span&gt; a m a &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; m a&lt;/span&gt;
&lt;span id=&quot;cb7-6&quot;&gt;&lt;a href=&quot;#cb7-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;runC ca &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; runContT ca &lt;span class=&quot;fu&quot;&gt;return&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb7-7&quot;&gt;&lt;a href=&quot;#cb7-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb7-8&quot;&gt;&lt;a href=&quot;#cb7-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;shift ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Monad&lt;/span&gt; m &lt;span class=&quot;ot&quot;&gt;=&amp;gt;&lt;/span&gt; ((a &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; m w) &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;ContT&lt;/span&gt; w m w) &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;ContT&lt;/span&gt; w m a&lt;/span&gt;
&lt;span id=&quot;cb7-9&quot;&gt;&lt;a href=&quot;#cb7-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;shift f &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;ContT&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; runC &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt; f&lt;/span&gt;
&lt;span id=&quot;cb7-10&quot;&gt;&lt;a href=&quot;#cb7-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb7-11&quot;&gt;&lt;a href=&quot;#cb7-11&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;decomposeContT&lt;/span&gt;
&lt;span id=&quot;cb7-12&quot;&gt;&lt;a href=&quot;#cb7-12&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;  ::&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;forall&lt;/span&gt; a w &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb7-13&quot;&gt;&lt;a href=&quot;#cb7-13&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;     (&lt;span class=&quot;kw&quot;&gt;forall&lt;/span&gt; r m &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;MonadIO&lt;/span&gt; m &lt;span class=&quot;ot&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;ContT&lt;/span&gt; r m a)&lt;/span&gt;
&lt;span id=&quot;cb7-14&quot;&gt;&lt;a href=&quot;#cb7-14&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;IO&lt;/span&gt; (a, &lt;span class=&quot;dt&quot;&gt;IO&lt;/span&gt; ()) &lt;span class=&quot;co&quot;&gt;-- the resource and its release action&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb7-15&quot;&gt;&lt;a href=&quot;#cb7-15&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;decomposeContT ca &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; runC &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; runContT ca &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; \a &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb7-16&quot;&gt;&lt;a href=&quot;#cb7-16&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  shift &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; \k &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb7-17&quot;&gt;&lt;a href=&quot;#cb7-17&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;kw&quot;&gt;let&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb7-18&quot;&gt;&lt;a href=&quot;#cb7-18&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;      r ::&lt;/span&gt; (a, &lt;span class=&quot;dt&quot;&gt;IO&lt;/span&gt; ())&lt;/span&gt;
&lt;span id=&quot;cb7-19&quot;&gt;&lt;a href=&quot;#cb7-19&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      r &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; (a, void &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; k r)&lt;/span&gt;
&lt;span id=&quot;cb7-20&quot;&gt;&lt;a href=&quot;#cb7-20&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;fu&quot;&gt;return&lt;/span&gt; r&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Here, &lt;code&gt;shift&lt;/code&gt; captures the current continuation delimited
by &lt;code&gt;runC&lt;/code&gt;; see &lt;a
href=&quot;http://okmij.org/ftp/continuations/Haskell-tutorial.pdf&quot;&gt;Oleg’s
delimited continuations tutorial&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Here is an example of how we can use decomposeContT. We generate two
random numbers and then “release” them in their increasing order:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb8&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb8-1&quot;&gt;&lt;a href=&quot;#cb8-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;System.Random&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb8-2&quot;&gt;&lt;a href=&quot;#cb8-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Text.Printf&lt;/span&gt; (printf)&lt;/span&gt;
&lt;span id=&quot;cb8-3&quot;&gt;&lt;a href=&quot;#cb8-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb8-4&quot;&gt;&lt;a href=&quot;#cb8-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;withRandomInt ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;MonadIO&lt;/span&gt; m &lt;span class=&quot;ot&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;ContT&lt;/span&gt; r m &lt;span class=&quot;dt&quot;&gt;Int&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb8-5&quot;&gt;&lt;a href=&quot;#cb8-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;withRandomInt &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;ContT&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; \k &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb8-6&quot;&gt;&lt;a href=&quot;#cb8-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;  n ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Int&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; liftIO &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; randomRIO (&lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;,&lt;span class=&quot;dv&quot;&gt;100&lt;/span&gt;)&lt;/span&gt;
&lt;span id=&quot;cb8-7&quot;&gt;&lt;a href=&quot;#cb8-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  liftIO &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; printf &lt;span class=&quot;st&quot;&gt;&amp;quot;Acquired number %d\n&amp;quot;&lt;/span&gt; n&lt;/span&gt;
&lt;span id=&quot;cb8-8&quot;&gt;&lt;a href=&quot;#cb8-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  r &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; k n&lt;/span&gt;
&lt;span id=&quot;cb8-9&quot;&gt;&lt;a href=&quot;#cb8-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  liftIO &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; printf &lt;span class=&quot;st&quot;&gt;&amp;quot;Released number %d\n&amp;quot;&lt;/span&gt; n&lt;/span&gt;
&lt;span id=&quot;cb8-10&quot;&gt;&lt;a href=&quot;#cb8-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;fu&quot;&gt;return&lt;/span&gt; r&lt;/span&gt;
&lt;span id=&quot;cb8-11&quot;&gt;&lt;a href=&quot;#cb8-11&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb8-12&quot;&gt;&lt;a href=&quot;#cb8-12&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;main &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb8-13&quot;&gt;&lt;a href=&quot;#cb8-13&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  (num1, release1) &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; decomposeContT withRandomInt&lt;/span&gt;
&lt;span id=&quot;cb8-14&quot;&gt;&lt;a href=&quot;#cb8-14&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  (num2, release2) &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; decomposeContT withRandomInt&lt;/span&gt;
&lt;span id=&quot;cb8-15&quot;&gt;&lt;a href=&quot;#cb8-15&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;if&lt;/span&gt; num1 &lt;span class=&quot;op&quot;&gt;&amp;lt;&lt;/span&gt; num2&lt;/span&gt;
&lt;span id=&quot;cb8-16&quot;&gt;&lt;a href=&quot;#cb8-16&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;kw&quot;&gt;then&lt;/span&gt; release1 &lt;span class=&quot;op&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt; release2&lt;/span&gt;
&lt;span id=&quot;cb8-17&quot;&gt;&lt;a href=&quot;#cb8-17&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;kw&quot;&gt;else&lt;/span&gt; release2 &lt;span class=&quot;op&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt; release1&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;However, this solution has a major drawback. It relies on the ability
to run our ContT action in a non-standard base monad (another ContT).
Therefore, it cannot be used to decompose
&lt;code&gt;ContT $ bracket acquire release&lt;/code&gt;, because bracket cannot run
in the &lt;code&gt;ContT&lt;/code&gt; monad.&lt;/p&gt;
&lt;h2 id=&quot;a-more-practical-solution&quot;&gt;A more practical solution&lt;/h2&gt;
&lt;p&gt;A less elegant solution, but one that actually solves real-world
problems, uses threads. Every resource is acquired in its own thread.
The thread then blocks on an MVar until it receives a signal that the
resource is no longer needed, in which case it proceeds to release
it.&lt;/p&gt;
&lt;p&gt;Here is the code.&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb9&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb9-1&quot;&gt;&lt;a href=&quot;#cb9-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;{-# LANGUAGE RankNTypes, ScopedTypeVariables #-}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb9-2&quot;&gt;&lt;a href=&quot;#cb9-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Control.Monad.Cont&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb9-3&quot;&gt;&lt;a href=&quot;#cb9-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Control.Concurrent&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb9-4&quot;&gt;&lt;a href=&quot;#cb9-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Control.Exception&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb9-5&quot;&gt;&lt;a href=&quot;#cb9-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb9-6&quot;&gt;&lt;a href=&quot;#cb9-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;ContCall&lt;/span&gt; a&lt;/span&gt;
&lt;span id=&quot;cb9-7&quot;&gt;&lt;a href=&quot;#cb9-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;ContException&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;dt&quot;&gt;SomeException&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb9-8&quot;&gt;&lt;a href=&quot;#cb9-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;co&quot;&gt;-- ^ an exception occurred before the continuation was called&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb9-9&quot;&gt;&lt;a href=&quot;#cb9-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;op&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;ContCall&lt;/span&gt; a&lt;/span&gt;
&lt;span id=&quot;cb9-10&quot;&gt;&lt;a href=&quot;#cb9-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;co&quot;&gt;-- ^ the continuation was called with this argument&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb9-11&quot;&gt;&lt;a href=&quot;#cb9-11&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;op&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;ContNoCall&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb9-12&quot;&gt;&lt;a href=&quot;#cb9-12&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;co&quot;&gt;-- ^ the ContT action returned wihtout ever calling the continuation&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb9-13&quot;&gt;&lt;a href=&quot;#cb9-13&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb9-14&quot;&gt;&lt;a href=&quot;#cb9-14&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;co&quot;&gt;-- | Retrieve a resource from a &amp;#39;ContT&amp;#39; action and return an action to&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb9-15&quot;&gt;&lt;a href=&quot;#cb9-15&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;co&quot;&gt;-- release it.&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb9-16&quot;&gt;&lt;a href=&quot;#cb9-16&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;decomposeContT ::&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;forall&lt;/span&gt; a &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt; (&lt;span class=&quot;kw&quot;&gt;forall&lt;/span&gt; r &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;ContT&lt;/span&gt; r &lt;span class=&quot;dt&quot;&gt;IO&lt;/span&gt; a) &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;IO&lt;/span&gt; (a, &lt;span class=&quot;dt&quot;&gt;IO&lt;/span&gt; ())&lt;/span&gt;
&lt;span id=&quot;cb9-17&quot;&gt;&lt;a href=&quot;#cb9-17&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;decomposeContT ca &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; mask &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; \restore &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb9-18&quot;&gt;&lt;a href=&quot;#cb9-18&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;co&quot;&gt;-- mvar_a is used to pass the &amp;#39;a&amp;#39; result (or an exception) from the ContT thread to the&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb9-19&quot;&gt;&lt;a href=&quot;#cb9-19&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;co&quot;&gt;-- calling thread&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb9-20&quot;&gt;&lt;a href=&quot;#cb9-20&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;  mvar_a ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;MVar&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;ContCall&lt;/span&gt; a) &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; newEmptyMVar&lt;/span&gt;
&lt;span id=&quot;cb9-21&quot;&gt;&lt;a href=&quot;#cb9-21&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;co&quot;&gt;-- mvar_r is used to signal the ContT thread that its resources can be&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb9-22&quot;&gt;&lt;a href=&quot;#cb9-22&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;co&quot;&gt;-- freed&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb9-23&quot;&gt;&lt;a href=&quot;#cb9-23&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;  mvar_r ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;MVar&lt;/span&gt; () &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; newEmptyMVar&lt;/span&gt;
&lt;span id=&quot;cb9-24&quot;&gt;&lt;a href=&quot;#cb9-24&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;co&quot;&gt;-- mvar_e is used to communicate a possible final exception to the&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb9-25&quot;&gt;&lt;a href=&quot;#cb9-25&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;co&quot;&gt;-- calling thread&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb9-26&quot;&gt;&lt;a href=&quot;#cb9-26&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;  mvar_e ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;MVar&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;Maybe&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;SomeException&lt;/span&gt;) &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; newEmptyMVar&lt;/span&gt;
&lt;span id=&quot;cb9-27&quot;&gt;&lt;a href=&quot;#cb9-27&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;let&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb9-28&quot;&gt;&lt;a href=&quot;#cb9-28&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;co&quot;&gt;-- tell the ContT thread to release its resources&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb9-29&quot;&gt;&lt;a href=&quot;#cb9-29&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;    freeResources ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;IO&lt;/span&gt; ()&lt;/span&gt;
&lt;span id=&quot;cb9-30&quot;&gt;&lt;a href=&quot;#cb9-30&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    freeResources &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; void &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; tryPutMVar mvar_r ()&lt;/span&gt;
&lt;span id=&quot;cb9-31&quot;&gt;&lt;a href=&quot;#cb9-31&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;co&quot;&gt;-- like freeResources, but also check and propagate any exception that&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb9-32&quot;&gt;&lt;a href=&quot;#cb9-32&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;co&quot;&gt;-- arose while trying to free the resource&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb9-33&quot;&gt;&lt;a href=&quot;#cb9-33&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;    freeResourcesCheckException ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;IO&lt;/span&gt; ()&lt;/span&gt;
&lt;span id=&quot;cb9-34&quot;&gt;&lt;a href=&quot;#cb9-34&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    freeResourcesCheckException &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb9-35&quot;&gt;&lt;a href=&quot;#cb9-35&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      void &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; tryPutMVar mvar_r ()&lt;/span&gt;
&lt;span id=&quot;cb9-36&quot;&gt;&lt;a href=&quot;#cb9-36&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      mb_e &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; readMVar mvar_e&lt;/span&gt;
&lt;span id=&quot;cb9-37&quot;&gt;&lt;a href=&quot;#cb9-37&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;fu&quot;&gt;maybe&lt;/span&gt; (&lt;span class=&quot;fu&quot;&gt;return&lt;/span&gt; ()) throwIO mb_e&lt;/span&gt;
&lt;span id=&quot;cb9-38&quot;&gt;&lt;a href=&quot;#cb9-38&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  pid &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; forkIO &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb9-39&quot;&gt;&lt;a href=&quot;#cb9-39&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;co&quot;&gt;----------------------------------------------------------------------&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb9-40&quot;&gt;&lt;a href=&quot;#cb9-40&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;co&quot;&gt;--             The code below runs in a new thread&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb9-41&quot;&gt;&lt;a href=&quot;#cb9-41&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;co&quot;&gt;----------------------------------------------------------------------&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb9-42&quot;&gt;&lt;a href=&quot;#cb9-42&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    r &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; try &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt; restore &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; runContT ca &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; \a &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb9-43&quot;&gt;&lt;a href=&quot;#cb9-43&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;co&quot;&gt;-- Try recording the argument of the continuation call in the MVar.&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb9-44&quot;&gt;&lt;a href=&quot;#cb9-44&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;co&quot;&gt;-- Might fail (return False) if this is not the first continuation&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb9-45&quot;&gt;&lt;a href=&quot;#cb9-45&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;co&quot;&gt;-- call, but we don&amp;#39;t care.&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb9-46&quot;&gt;&lt;a href=&quot;#cb9-46&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;      _ ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Bool&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; tryPutMVar mvar_a (&lt;span class=&quot;dt&quot;&gt;ContCall&lt;/span&gt; a)&lt;/span&gt;
&lt;span id=&quot;cb9-47&quot;&gt;&lt;a href=&quot;#cb9-47&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;co&quot;&gt;-- Then wait until it&amp;#39;s ok to free the resources.&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb9-48&quot;&gt;&lt;a href=&quot;#cb9-48&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      () &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; readMVar mvar_r&lt;/span&gt;
&lt;span id=&quot;cb9-49&quot;&gt;&lt;a href=&quot;#cb9-49&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;fu&quot;&gt;return&lt;/span&gt; ()&lt;/span&gt;
&lt;span id=&quot;cb9-50&quot;&gt;&lt;a href=&quot;#cb9-50&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;kw&quot;&gt;case&lt;/span&gt; r &lt;span class=&quot;kw&quot;&gt;of&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb9-51&quot;&gt;&lt;a href=&quot;#cb9-51&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;dt&quot;&gt;Right&lt;/span&gt; () &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb9-52&quot;&gt;&lt;a href=&quot;#cb9-52&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;        &lt;span class=&quot;co&quot;&gt;-- The ContT action returned successfully. We don&amp;#39;t know how many&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb9-53&quot;&gt;&lt;a href=&quot;#cb9-53&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;        &lt;span class=&quot;co&quot;&gt;-- times the continuation was called. Try putting ContNoCall in&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb9-54&quot;&gt;&lt;a href=&quot;#cb9-54&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;        &lt;span class=&quot;co&quot;&gt;-- case it wasn&amp;#39;t called at all. If it was called, then tryPutMVar&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb9-55&quot;&gt;&lt;a href=&quot;#cb9-55&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;        &lt;span class=&quot;co&quot;&gt;-- will return False; we don&amp;#39;t care.&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb9-56&quot;&gt;&lt;a href=&quot;#cb9-56&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;        _ ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Bool&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; tryPutMVar mvar_a &lt;span class=&quot;dt&quot;&gt;ContNoCall&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb9-57&quot;&gt;&lt;a href=&quot;#cb9-57&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;        _ ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Bool&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; tryPutMVar mvar_e &lt;span class=&quot;dt&quot;&gt;Nothing&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb9-58&quot;&gt;&lt;a href=&quot;#cb9-58&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;        &lt;span class=&quot;fu&quot;&gt;return&lt;/span&gt; ()&lt;/span&gt;
&lt;span id=&quot;cb9-59&quot;&gt;&lt;a href=&quot;#cb9-59&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;dt&quot;&gt;Left&lt;/span&gt; e &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb9-60&quot;&gt;&lt;a href=&quot;#cb9-60&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;        &lt;span class=&quot;co&quot;&gt;-- An exception was raised. We don&amp;#39;t know whether it was before or&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb9-61&quot;&gt;&lt;a href=&quot;#cb9-61&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;        &lt;span class=&quot;co&quot;&gt;-- after the continuation was called. Try putting the exception in&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb9-62&quot;&gt;&lt;a href=&quot;#cb9-62&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;        &lt;span class=&quot;co&quot;&gt;-- both mvar_r and mvar_e so that it surfaces exactly once&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb9-63&quot;&gt;&lt;a href=&quot;#cb9-63&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;        &lt;span class=&quot;co&quot;&gt;-- (assuming the cleanup function eventually gets called) in the&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb9-64&quot;&gt;&lt;a href=&quot;#cb9-64&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;        &lt;span class=&quot;co&quot;&gt;-- calling thread.&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb9-65&quot;&gt;&lt;a href=&quot;#cb9-65&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;        _ ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Bool&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; tryPutMVar mvar_a &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;ContException&lt;/span&gt; e&lt;/span&gt;
&lt;span id=&quot;cb9-66&quot;&gt;&lt;a href=&quot;#cb9-66&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;        _ ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Bool&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; tryPutMVar mvar_e &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Just&lt;/span&gt; e&lt;/span&gt;
&lt;span id=&quot;cb9-67&quot;&gt;&lt;a href=&quot;#cb9-67&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;        &lt;span class=&quot;fu&quot;&gt;return&lt;/span&gt; ()&lt;/span&gt;
&lt;span id=&quot;cb9-68&quot;&gt;&lt;a href=&quot;#cb9-68&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;co&quot;&gt;----------------------------------------------------------------------&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb9-69&quot;&gt;&lt;a href=&quot;#cb9-69&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;co&quot;&gt;--             The code above runs in a new thread&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb9-70&quot;&gt;&lt;a href=&quot;#cb9-70&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;co&quot;&gt;----------------------------------------------------------------------&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb9-71&quot;&gt;&lt;a href=&quot;#cb9-71&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb9-72&quot;&gt;&lt;a href=&quot;#cb9-72&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;co&quot;&gt;-- Now, in the calling thread, we wait until mvar_a is filled&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb9-73&quot;&gt;&lt;a href=&quot;#cb9-73&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;co&quot;&gt;-- readMVar is blocking, so it may receive exceptions. If there is&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb9-74&quot;&gt;&lt;a href=&quot;#cb9-74&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;co&quot;&gt;-- an exception, we also send it to the ContT thread.&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb9-75&quot;&gt;&lt;a href=&quot;#cb9-75&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  contCall &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; readMVar mvar_a &lt;span class=&quot;ot&quot;&gt;`catch`&lt;/span&gt; (\(&lt;span class=&quot;ot&quot;&gt;e ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;SomeException&lt;/span&gt;) &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;do&lt;/span&gt; throwTo pid e; throwIO e)&lt;/span&gt;
&lt;span id=&quot;cb9-76&quot;&gt;&lt;a href=&quot;#cb9-76&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;case&lt;/span&gt; contCall &lt;span class=&quot;kw&quot;&gt;of&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb9-77&quot;&gt;&lt;a href=&quot;#cb9-77&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;dt&quot;&gt;ContCall&lt;/span&gt; a &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;return&lt;/span&gt; (a, freeResourcesCheckException)&lt;/span&gt;
&lt;span id=&quot;cb9-78&quot;&gt;&lt;a href=&quot;#cb9-78&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;dt&quot;&gt;ContException&lt;/span&gt; e &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb9-79&quot;&gt;&lt;a href=&quot;#cb9-79&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      freeResources&lt;/span&gt;
&lt;span id=&quot;cb9-80&quot;&gt;&lt;a href=&quot;#cb9-80&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      throwIO e&lt;/span&gt;
&lt;span id=&quot;cb9-81&quot;&gt;&lt;a href=&quot;#cb9-81&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;dt&quot;&gt;ContNoCall&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb9-82&quot;&gt;&lt;a href=&quot;#cb9-82&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      freeResources&lt;/span&gt;
&lt;span id=&quot;cb9-83&quot;&gt;&lt;a href=&quot;#cb9-83&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      throwIO &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;ErrorCall&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;quot;decomposeContT: the continuation was never called&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;section id=&quot;footnotes&quot; class=&quot;footnotes footnotes-end-of-document&quot;
role=&quot;doc-endnotes&quot;&gt;
&lt;hr /&gt;
&lt;ol&gt;
&lt;li id=&quot;fn1&quot;&gt;&lt;p&gt;Or, more precisely, &lt;code&gt;release x&lt;/code&gt;, where
&lt;code&gt;x&lt;/code&gt; is the value returned by &lt;code&gt;acquire&lt;/code&gt;. We cannot
infer how &lt;code&gt;release&lt;/code&gt; would act on any other value, of
course.&lt;a href=&quot;#fnref1&quot; class=&quot;footnote-back&quot;
role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</description>
                        <pubDate>Fri, 19 Jul 2019 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2019-07-19-decompose-contt</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2019-07-19-decompose-contt.html</guid>
                </item>
        
                <item>
                        <title>Why would you use ContT?</title>
                        <description>&lt;p&gt;The &lt;a
href=&quot;https://hackage.haskell.org/package/mtl-2.2.2/docs/Control-Monad-Cont.html#g:3&quot;&gt;ContT
transformer&lt;/a&gt; is one of the more exotic and less used transformers
provided by mtl. The &lt;code&gt;Control.Monad.Cont&lt;/code&gt; module now even
includes the following warning:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Before using the Continuation monad, be sure that you have a firm
understanding of continuation-passing style and that continuations
represent the best solution to your particular design problem. Many
algorithms which require continuations in other languages do not require
them in Haskell, due to Haskell’s lazy semantics. Abuse of the
Continuation monad can produce code that is impossible to understand and
maintain.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;So what is ContT, and when &lt;em&gt;does it&lt;/em&gt; represent the best
solution to a problem?&lt;/p&gt;
&lt;p&gt;Consider the following three functions from the base library:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb1&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb1-1&quot;&gt;&lt;a href=&quot;#cb1-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;openFile ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;FilePath&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;IOMode&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;IO&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Handle&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-2&quot;&gt;&lt;a href=&quot;#cb1-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;takeMVar ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;MVar&lt;/span&gt; a             &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;IO&lt;/span&gt; a&lt;/span&gt;
&lt;span id=&quot;cb1-3&quot;&gt;&lt;a href=&quot;#cb1-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;newArray ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Storable&lt;/span&gt; a &lt;span class=&quot;ot&quot;&gt;=&amp;gt;&lt;/span&gt; [a]  &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;IO&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;Ptr&lt;/span&gt; a)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;They are all “unsafe” in the sense that they return something to you
but don’t clean up after you: don’t close the file you’ve just opened,
put back the MVar you’ve just taken, or free the array’s memory. If you
forget to perform the cleanup, it’s on you.&lt;/p&gt;
&lt;p&gt;Indeed, a function that closed the file right after opening it would
be rather useless. Therefore, a “safer” function should know what you
intend to do with the file handle and insert that action between opening
and closing the file.&lt;/p&gt;
&lt;p&gt;The base library provides the following safer versions of the above
functions:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb2&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb2-1&quot;&gt;&lt;a href=&quot;#cb2-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;                                 &lt;span class=&quot;co&quot;&gt;{-~~~~~~~~~~~~~~~~~~~~~~~~-}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-2&quot;&gt;&lt;a href=&quot;#cb2-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;withFile ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;FilePath&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;IOMode&lt;/span&gt;  &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;Handle&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;IO&lt;/span&gt; r) &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;IO&lt;/span&gt; r&lt;/span&gt;
&lt;span id=&quot;cb2-3&quot;&gt;&lt;a href=&quot;#cb2-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;withMVar ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;MVar&lt;/span&gt; a              &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; (a      &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;IO&lt;/span&gt; r) &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;IO&lt;/span&gt; r&lt;/span&gt;
&lt;span id=&quot;cb2-4&quot;&gt;&lt;a href=&quot;#cb2-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;withArray ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Storable&lt;/span&gt; a &lt;span class=&quot;ot&quot;&gt;=&amp;gt;&lt;/span&gt; [a]  &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;Ptr&lt;/span&gt; a  &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;IO&lt;/span&gt; r) &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;IO&lt;/span&gt; r&lt;/span&gt;
&lt;span id=&quot;cb2-5&quot;&gt;&lt;a href=&quot;#cb2-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;                                 &lt;span class=&quot;co&quot;&gt;{-~~~~~~~~~~~~~~~~~~~~~~~~-}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Notice how these functions follow the same pattern and how they
relate to their unsafe versions: if the unsafe function returned
&lt;code&gt;IO a&lt;/code&gt;, then the corresponding safe function takes an
additional argument of the form &lt;code&gt;(a -&amp;gt; IO r)&lt;/code&gt; and returns
&lt;code&gt;IO r&lt;/code&gt;. This style of writing functions is called the
&lt;em&gt;continuation-passing style&lt;/em&gt; (CPS), and the argument
&lt;code&gt;a -&amp;gt; IO r&lt;/code&gt; is called the &lt;em&gt;continuation&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;ContT&lt;/code&gt; gives this pattern its own type:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb3&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb3-1&quot;&gt;&lt;a href=&quot;#cb3-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;newtype&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;ContT&lt;/span&gt; r m a &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;ContT&lt;/span&gt; {&lt;span class=&quot;ot&quot;&gt; runContT ::&lt;/span&gt; (a &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; m r) &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; m r }&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;(In this article, the underlying monad &lt;code&gt;m&lt;/code&gt; will always be
&lt;code&gt;IO&lt;/code&gt;.)&lt;/p&gt;
&lt;p&gt;You can construct &lt;code&gt;ContT&lt;/code&gt; functions from the functions
written in the CPS:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb4&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb4-1&quot;&gt;&lt;a href=&quot;#cb4-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;\v   &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;ContT&lt;/span&gt; (withMVar v)&lt;span class=&quot;ot&quot;&gt;   ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;MVar&lt;/span&gt; a             &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;ContT&lt;/span&gt; r &lt;span class=&quot;dt&quot;&gt;IO&lt;/span&gt; a&lt;/span&gt;
&lt;span id=&quot;cb4-2&quot;&gt;&lt;a href=&quot;#cb4-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;\f m &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;ContT&lt;/span&gt; (withFile f m)&lt;span class=&quot;ot&quot;&gt; ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;FilePath&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;IOMode&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;ContT&lt;/span&gt; r &lt;span class=&quot;dt&quot;&gt;IO&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Handle&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-3&quot;&gt;&lt;a href=&quot;#cb4-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;\l   &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;ContT&lt;/span&gt; (withArray l)&lt;span class=&quot;ot&quot;&gt;  ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Storable&lt;/span&gt; a &lt;span class=&quot;ot&quot;&gt;=&amp;gt;&lt;/span&gt; [a]  &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;ContT&lt;/span&gt; r &lt;span class=&quot;dt&quot;&gt;IO&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;Ptr&lt;/span&gt; a)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Notice how the types of the safe functions, once wrapped in
&lt;code&gt;ContT&lt;/code&gt;, become even more similar to the types of their
non-safe versions: the only difference is &lt;code&gt;ContT r IO&lt;/code&gt;
instead of &lt;code&gt;IO&lt;/code&gt; in the return type. And because
&lt;code&gt;ContT&lt;/code&gt; turns out to be a monad transformer, we can use and
combine the safe function in all the same way as we could with the
unsafe functions—getting the added safety essentially for free. Once you
no longer need the resources you’ve allocated inside &lt;code&gt;ContT&lt;/code&gt;,
you turn it to &lt;code&gt;IO&lt;/code&gt; using &lt;code&gt;runContT&lt;/code&gt;, and when you
exit a &lt;code&gt;ContT&lt;/code&gt; block, all the cleanup actions are run—in the
reverse order, of course.&lt;/p&gt;
&lt;p&gt;Let’s consider some practical examples.&lt;/p&gt;
&lt;h2 id=&quot;llvm-hs&quot;&gt;llvm-hs&lt;/h2&gt;
&lt;p&gt;In the &lt;a
href=&quot;https://hackage.haskell.org/package/llvm-hs-8.0.0&quot;&gt;llvm-hs&lt;/a&gt;
package’s API, the continuation-passing style is used to reliably
deallocate the allocated LLVM structures and classes, which are written
in C++.&lt;/p&gt;
&lt;p&gt;Here’s an example from llvm-hs’s test suite, reformatted such that
each nesting level gets its own indentation level:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb5&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb5-1&quot;&gt;&lt;a href=&quot;#cb5-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;testCase &lt;span class=&quot;st&quot;&gt;&amp;quot;eager compilation&amp;quot;&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-2&quot;&gt;&lt;a href=&quot;#cb5-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  resolvers &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; newIORef Map.empty&lt;/span&gt;
&lt;span id=&quot;cb5-3&quot;&gt;&lt;a href=&quot;#cb5-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  withTestModule &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; \&lt;span class=&quot;fu&quot;&gt;mod&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-4&quot;&gt;&lt;a href=&quot;#cb5-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    withHostTargetMachine &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; \tm &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-5&quot;&gt;&lt;a href=&quot;#cb5-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      withExecutionSession &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; \es &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-6&quot;&gt;&lt;a href=&quot;#cb5-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;        withObjectLinkingLayer es (\k &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;fmap&lt;/span&gt; (\rs &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; rs &lt;span class=&quot;op&quot;&gt;Map.!&lt;/span&gt; k) (readIORef resolvers)) &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; \linkingLayer &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-7&quot;&gt;&lt;a href=&quot;#cb5-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;          withIRCompileLayer linkingLayer tm &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; \compileLayer &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-8&quot;&gt;&lt;a href=&quot;#cb5-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;            testFunc &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; mangleSymbol compileLayer &lt;span class=&quot;st&quot;&gt;&amp;quot;testFunc&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-9&quot;&gt;&lt;a href=&quot;#cb5-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;            withModuleKey es &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; \k &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-10&quot;&gt;&lt;a href=&quot;#cb5-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;              withSymbolResolver es (&lt;span class=&quot;dt&quot;&gt;SymbolResolver&lt;/span&gt; (resolver testFunc compileLayer)) &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; \resolver &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-11&quot;&gt;&lt;a href=&quot;#cb5-11&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;                modifyIORef&amp;#39; resolvers (Map.insert k resolver)&lt;/span&gt;
&lt;span id=&quot;cb5-12&quot;&gt;&lt;a href=&quot;#cb5-12&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;                withModule compileLayer k &lt;span class=&quot;fu&quot;&gt;mod&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-13&quot;&gt;&lt;a href=&quot;#cb5-13&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;                  mainSymbol &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; mangleSymbol compileLayer &lt;span class=&quot;st&quot;&gt;&amp;quot;main&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-14&quot;&gt;&lt;a href=&quot;#cb5-14&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;                  &lt;span class=&quot;dt&quot;&gt;Right&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;JITSymbol&lt;/span&gt; mainFn _) &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; CL.findSymbol compileLayer mainSymbol &lt;span class=&quot;dt&quot;&gt;True&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-15&quot;&gt;&lt;a href=&quot;#cb5-15&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;                  result &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; mkMain (castPtrToFunPtr (wordPtrToPtr mainFn))&lt;/span&gt;
&lt;span id=&quot;cb5-16&quot;&gt;&lt;a href=&quot;#cb5-16&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;                  result &lt;span class=&quot;op&quot;&gt;@?=&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;42&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-17&quot;&gt;&lt;a href=&quot;#cb5-17&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;                  &lt;span class=&quot;dt&quot;&gt;Right&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;JITSymbol&lt;/span&gt; mainFn _) &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; CL.findSymbolIn compileLayer k mainSymbol &lt;span class=&quot;dt&quot;&gt;True&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-18&quot;&gt;&lt;a href=&quot;#cb5-18&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;                  result &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; mkMain (castPtrToFunPtr (wordPtrToPtr mainFn))&lt;/span&gt;
&lt;span id=&quot;cb5-19&quot;&gt;&lt;a href=&quot;#cb5-19&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;                  result &lt;span class=&quot;op&quot;&gt;@?=&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;42&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-20&quot;&gt;&lt;a href=&quot;#cb5-20&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;                  unknownSymbol &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; mangleSymbol compileLayer &lt;span class=&quot;st&quot;&gt;&amp;quot;unknownSymbol&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-21&quot;&gt;&lt;a href=&quot;#cb5-21&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;                  unknownSymbolRes &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; CL.findSymbol compileLayer unknownSymbol &lt;span class=&quot;dt&quot;&gt;True&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-22&quot;&gt;&lt;a href=&quot;#cb5-22&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;                  unknownSymbolRes &lt;span class=&quot;op&quot;&gt;@?=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Left&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;JITSymbolError&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;mempty&lt;/span&gt;),&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;And here’s the same test rewritten with &lt;code&gt;ContT&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb6&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb6-1&quot;&gt;&lt;a href=&quot;#cb6-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;testCase &lt;span class=&quot;st&quot;&gt;&amp;quot;eager compilation&amp;quot;&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-2&quot;&gt;&lt;a href=&quot;#cb6-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;fu&quot;&gt;flip&lt;/span&gt; runContT &lt;span class=&quot;fu&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-3&quot;&gt;&lt;a href=&quot;#cb6-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    resolvers &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; liftIO &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; newIORef Map.empty&lt;/span&gt;
&lt;span id=&quot;cb6-4&quot;&gt;&lt;a href=&quot;#cb6-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;fu&quot;&gt;mod&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;ContT&lt;/span&gt; withTestModule&lt;/span&gt;
&lt;span id=&quot;cb6-5&quot;&gt;&lt;a href=&quot;#cb6-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    tm &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;ContT&lt;/span&gt; withHostTargetMachine&lt;/span&gt;
&lt;span id=&quot;cb6-6&quot;&gt;&lt;a href=&quot;#cb6-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    es &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;ContT&lt;/span&gt; withExecutionSession&lt;/span&gt;
&lt;span id=&quot;cb6-7&quot;&gt;&lt;a href=&quot;#cb6-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    linkingLayer &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;ContT&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; withObjectLinkingLayer es (\k &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;fmap&lt;/span&gt; (\rs &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; rs &lt;span class=&quot;op&quot;&gt;Map.!&lt;/span&gt; k) (readIORef resolvers))&lt;/span&gt;
&lt;span id=&quot;cb6-8&quot;&gt;&lt;a href=&quot;#cb6-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    compileLayer &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;ContT&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; withIRCompileLayer linkingLayer tm&lt;/span&gt;
&lt;span id=&quot;cb6-9&quot;&gt;&lt;a href=&quot;#cb6-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    testFunc &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; liftIO &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; mangleSymbol compileLayer &lt;span class=&quot;st&quot;&gt;&amp;quot;testFunc&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-10&quot;&gt;&lt;a href=&quot;#cb6-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    k &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;ContT&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; withModuleKey es&lt;/span&gt;
&lt;span id=&quot;cb6-11&quot;&gt;&lt;a href=&quot;#cb6-11&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    resolver &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;ContT&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; withSymbolResolver es (&lt;span class=&quot;dt&quot;&gt;SymbolResolver&lt;/span&gt; (resolver testFunc compileLayer))&lt;/span&gt;
&lt;span id=&quot;cb6-12&quot;&gt;&lt;a href=&quot;#cb6-12&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    liftIO &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; modifyIORef&amp;#39; resolvers (Map.insert k resolver)&lt;/span&gt;
&lt;span id=&quot;cb6-13&quot;&gt;&lt;a href=&quot;#cb6-13&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;dt&quot;&gt;ContT&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; \c &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; withModule compileLayer k &lt;span class=&quot;fu&quot;&gt;mod&lt;/span&gt; (c ())&lt;/span&gt;
&lt;span id=&quot;cb6-14&quot;&gt;&lt;a href=&quot;#cb6-14&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;co&quot;&gt;-- All functions below are non-CPS, so we combine them into a single IO block&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-15&quot;&gt;&lt;a href=&quot;#cb6-15&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;co&quot;&gt;-- instead of applying liftIO on every line.&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-16&quot;&gt;&lt;a href=&quot;#cb6-16&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    liftIO &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-17&quot;&gt;&lt;a href=&quot;#cb6-17&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      mainSymbol &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; mangleSymbol compileLayer &lt;span class=&quot;st&quot;&gt;&amp;quot;main&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-18&quot;&gt;&lt;a href=&quot;#cb6-18&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;dt&quot;&gt;Right&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;JITSymbol&lt;/span&gt; mainFn _) &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; CL.findSymbol compileLayer mainSymbol &lt;span class=&quot;dt&quot;&gt;True&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-19&quot;&gt;&lt;a href=&quot;#cb6-19&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      result &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; mkMain (castPtrToFunPtr (wordPtrToPtr mainFn))&lt;/span&gt;
&lt;span id=&quot;cb6-20&quot;&gt;&lt;a href=&quot;#cb6-20&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      result &lt;span class=&quot;op&quot;&gt;@?=&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;42&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-21&quot;&gt;&lt;a href=&quot;#cb6-21&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;dt&quot;&gt;Right&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;JITSymbol&lt;/span&gt; mainFn _) &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; CL.findSymbolIn compileLayer k mainSymbol &lt;span class=&quot;dt&quot;&gt;True&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-22&quot;&gt;&lt;a href=&quot;#cb6-22&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      result &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; mkMain (castPtrToFunPtr (wordPtrToPtr mainFn))&lt;/span&gt;
&lt;span id=&quot;cb6-23&quot;&gt;&lt;a href=&quot;#cb6-23&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      result &lt;span class=&quot;op&quot;&gt;@?=&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;42&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-24&quot;&gt;&lt;a href=&quot;#cb6-24&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      unknownSymbol &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; mangleSymbol compileLayer &lt;span class=&quot;st&quot;&gt;&amp;quot;unknownSymbol&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-25&quot;&gt;&lt;a href=&quot;#cb6-25&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      unknownSymbolRes &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; CL.findSymbol compileLayer unknownSymbol &lt;span class=&quot;dt&quot;&gt;True&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-26&quot;&gt;&lt;a href=&quot;#cb6-26&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      unknownSymbolRes &lt;span class=&quot;op&quot;&gt;@?=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Left&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;JITSymbolError&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;mempty&lt;/span&gt;),&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Most of the nesting and indentation is gone. The code is completely
linear now, just as if we were using the unsafe, non-CPS functions.
Applying &lt;code&gt;ContT&lt;/code&gt; on every line is a bit awkward, but that
would be gone if the library’s API was designed so that the CPS
functions were already in the &lt;code&gt;ContT&lt;/code&gt; monad.&lt;/p&gt;
&lt;h2 id=&quot;reading-from-a-list-of-files&quot;&gt;Reading from a list of files&lt;/h2&gt;
&lt;p&gt;In the above example, we had merely a &lt;em&gt;high&lt;/em&gt; nesting level.
But what if the nesting level is &lt;em&gt;unknown&lt;/em&gt; in advance?&lt;/p&gt;
&lt;p&gt;Consider a program that takes a list of files and prints them
interleaved—a line from the first file, then a line from the second, and
so on, printing the line &lt;em&gt;m+1&lt;/em&gt; of the first file after the line
&lt;em&gt;m&lt;/em&gt; of the last file.&lt;/p&gt;
&lt;p&gt;To implement such a program, we need to keep all the &lt;em&gt;n&lt;/em&gt; files
open all the time. If we want to use the safe &lt;code&gt;withFile&lt;/code&gt;
function, we need to nest it &lt;em&gt;n&lt;/em&gt; times, where &lt;em&gt;n&lt;/em&gt; is not
known until the program is run. How is that even possible?&lt;/p&gt;
&lt;p&gt;Well, it is possible with &lt;code&gt;ContT&lt;/code&gt;.&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb7&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb7-1&quot;&gt;&lt;a href=&quot;#cb7-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Control.Monad.Cont&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb7-2&quot;&gt;&lt;a href=&quot;#cb7-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;System.IO&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb7-3&quot;&gt;&lt;a href=&quot;#cb7-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;System.Environment&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb7-4&quot;&gt;&lt;a href=&quot;#cb7-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb7-5&quot;&gt;&lt;a href=&quot;#cb7-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;main &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;flip&lt;/span&gt; runContT &lt;span class=&quot;fu&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb7-6&quot;&gt;&lt;a href=&quot;#cb7-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  args &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; liftIO getArgs&lt;/span&gt;
&lt;span id=&quot;cb7-7&quot;&gt;&lt;a href=&quot;#cb7-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  handles &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; forM args &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; \arg &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb7-8&quot;&gt;&lt;a href=&quot;#cb7-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;dt&quot;&gt;ContT&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; withFile arg &lt;span class=&quot;dt&quot;&gt;ReadMode&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb7-9&quot;&gt;&lt;a href=&quot;#cb7-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  liftIO &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; print_interleaved_from_handles handles&lt;/span&gt;
&lt;span id=&quot;cb7-10&quot;&gt;&lt;a href=&quot;#cb7-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb7-11&quot;&gt;&lt;a href=&quot;#cb7-11&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;print_interleaved_from_handles ::&lt;/span&gt; [&lt;span class=&quot;dt&quot;&gt;Handle&lt;/span&gt;] &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;IO&lt;/span&gt; ()&lt;/span&gt;
&lt;span id=&quot;cb7-12&quot;&gt;&lt;a href=&quot;#cb7-12&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;print_interleaved_from_handles &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;...&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;allocating-a-linked-list&quot;&gt;Allocating a linked list&lt;/h2&gt;
&lt;p&gt;This example is similar to the previous one, except it actually
occurred in my practice. See Way 2 in &lt;a
href=&quot;/articles/2017-08-06-manage-allocated-memory-haskell&quot;&gt;6 ways to
manage allocated memory in Haskell&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;withX&lt;/code&gt;-style safe functions are far from the only
possible use for CPS and &lt;code&gt;ContT&lt;/code&gt;, but it’s the one that I
encounter most often. So if you were wondering why you’d use a
continuation monad, hopefully this gives you some ideas.&lt;/p&gt;
</description>
                        <pubDate>Fri, 07 Jun 2019 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2019-06-07-why-use-contt</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2019-06-07-why-use-contt.html</guid>
                </item>
        
                <item>
                        <title>How (not) to convert CDouble to Double</title>
                        <description>&lt;p&gt;What’s wrong with the following code?&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb1&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb1-1&quot;&gt;&lt;a href=&quot;#cb1-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;module&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Acos&lt;/span&gt; (&lt;span class=&quot;fu&quot;&gt;acos&lt;/span&gt;) &lt;span class=&quot;kw&quot;&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-2&quot;&gt;&lt;a href=&quot;#cb1-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-3&quot;&gt;&lt;a href=&quot;#cb1-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Prelude&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;hiding&lt;/span&gt; (acos)&lt;/span&gt;
&lt;span id=&quot;cb1-4&quot;&gt;&lt;a href=&quot;#cb1-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Foreign.C.Types&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;CDouble&lt;/span&gt;(..))&lt;/span&gt;
&lt;span id=&quot;cb1-5&quot;&gt;&lt;a href=&quot;#cb1-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-6&quot;&gt;&lt;a href=&quot;#cb1-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;foreign &lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; ccall &amp;quot;math.h acos&amp;quot; c_acos :: &lt;span class=&quot;dt&quot;&gt;CDouble&lt;/span&gt; -&amp;gt; &lt;span class=&quot;dt&quot;&gt;CDouble&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-7&quot;&gt;&lt;a href=&quot;#cb1-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-8&quot;&gt;&lt;a href=&quot;#cb1-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;fu&quot;&gt;acos&lt;/span&gt;&lt;span class=&quot;ot&quot;&gt; ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Double&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Double&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-9&quot;&gt;&lt;a href=&quot;#cb1-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;fu&quot;&gt;acos&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;realToFrac&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt; c_acos &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;realToFrac&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;If you use QuickCheck to test the equivalence of
&lt;code&gt;Acos.acos&lt;/code&gt; and &lt;code&gt;Prelude.acos&lt;/code&gt;, you’ll quickly
find a counterexample:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb2&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb2-1&quot;&gt;&lt;a href=&quot;#cb2-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;op&quot;&gt;&amp;gt;&lt;/span&gt; Prelude.acos &lt;span class=&quot;fl&quot;&gt;1.1&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-2&quot;&gt;&lt;a href=&quot;#cb2-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;dt&quot;&gt;NaN&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-3&quot;&gt;&lt;a href=&quot;#cb2-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;op&quot;&gt;&amp;gt;&lt;/span&gt; Acos.acos &lt;span class=&quot;fl&quot;&gt;1.1&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-4&quot;&gt;&lt;a href=&quot;#cb2-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;dt&quot;&gt;Infinity&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;You might think this is a difference in the semantics of Haskell acos
vs. C acos, but the &lt;a
href=&quot;https://linux.die.net/man/3/acos&quot;&gt;acos(3)&lt;/a&gt; manpage disproves
that:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;If x is outside the range [-1, 1], a domain error occurs, and a NaN
is returned.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Moreover, you’ll notice the discrepancy only when compiling the
Haskell program with &lt;code&gt;-O0&lt;/code&gt;. If you compile with
&lt;code&gt;-O1&lt;/code&gt; or higher, both versions will result in
&lt;code&gt;NaN&lt;/code&gt;. So what’s going on here?&lt;/p&gt;
&lt;p&gt;What turns the &lt;code&gt;NaN&lt;/code&gt; turned into the &lt;code&gt;Infinity&lt;/code&gt;
is &lt;code&gt;realToFrac&lt;/code&gt;. It is defined as follows:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb3&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb3-1&quot;&gt;&lt;a href=&quot;#cb3-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;fu&quot;&gt;realToFrac&lt;/span&gt;&lt;span class=&quot;ot&quot;&gt; ::&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;Real&lt;/span&gt; a, &lt;span class=&quot;dt&quot;&gt;Fractional&lt;/span&gt; b) &lt;span class=&quot;ot&quot;&gt;=&amp;gt;&lt;/span&gt; a &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; b&lt;/span&gt;
&lt;span id=&quot;cb3-2&quot;&gt;&lt;a href=&quot;#cb3-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;fu&quot;&gt;realToFrac&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;fromRational&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;toRational&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Unlike &lt;code&gt;Double&lt;/code&gt;, &lt;code&gt;Rational&lt;/code&gt;, which is defined
as a ratio of two Integers, has no way to represent special values such
as &lt;code&gt;NaN&lt;/code&gt;. Instead, &lt;code&gt;toRational (acos 1.1)&lt;/code&gt; results
in a fraction with some ridiculously large numerator, which turns into
&lt;code&gt;Infinity&lt;/code&gt; when converted back to &lt;code&gt;Double&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;When you compile with &lt;code&gt;-O1&lt;/code&gt; or higher, the following
rewrite rules fire and avoid the round trip through
&lt;code&gt;Rational&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb4&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb4-1&quot;&gt;&lt;a href=&quot;#cb4-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;st&quot;&gt;&amp;quot;realToFrac/a-&amp;gt;CDouble&amp;quot;&lt;/span&gt;     &lt;span class=&quot;fu&quot;&gt;realToFrac&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; \x &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;CDouble&lt;/span&gt;  (&lt;span class=&quot;fu&quot;&gt;realToFrac&lt;/span&gt; x)&lt;/span&gt;
&lt;span id=&quot;cb4-2&quot;&gt;&lt;a href=&quot;#cb4-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;st&quot;&gt;&amp;quot;realToFrac/CDouble-&amp;gt;a&amp;quot;&lt;/span&gt;     &lt;span class=&quot;fu&quot;&gt;realToFrac&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; \(&lt;span class=&quot;dt&quot;&gt;CDouble&lt;/span&gt;  x) &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;realToFrac&lt;/span&gt; x&lt;/span&gt;
&lt;span id=&quot;cb4-3&quot;&gt;&lt;a href=&quot;#cb4-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;st&quot;&gt;&amp;quot;realToFrac/Double-&amp;gt;Double&amp;quot;&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;realToFrac&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;= id ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Double&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Double&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Unfortunately, the &lt;a
href=&quot;https://www.haskell.org/onlinereport/haskell2010/haskellch28.html#x36-27800028.1.3&quot;&gt;Haskell
2010 Report&lt;/a&gt; doesn’t give you any reliable way to convert between
&lt;code&gt;Double&lt;/code&gt; and &lt;code&gt;CDouble&lt;/code&gt;. According to the Report,
&lt;code&gt;CDouble&lt;/code&gt; is an abstract newtype, about which all you know is
the list of instances, including &lt;code&gt;Real&lt;/code&gt; and
&lt;code&gt;Fractional&lt;/code&gt;. So if you want to stay portable,
&lt;code&gt;realToFrac&lt;/code&gt; seems to be the only solution available.&lt;/p&gt;
&lt;p&gt;However, if you only care about GHC and its base library (which
pretty much everyone is using nowadays), then you can take advantage of
the fact that the constructor of the &lt;code&gt;CDouble&lt;/code&gt; newtype is &lt;a
href=&quot;https://hackage.haskell.org/package/base-4.12.0.0/docs/Foreign-C-Types.html#t:CDouble&quot;&gt;exported&lt;/a&gt;.
You can use &lt;code&gt;coerce&lt;/code&gt; from &lt;code&gt;Data.Coerce&lt;/code&gt; or apply
the data constructor &lt;code&gt;CDouble&lt;/code&gt; directly.&lt;/p&gt;
&lt;p&gt;So here’s a reliable, but not portable, version of the
&lt;code&gt;Acos&lt;/code&gt; module above:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb5&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb5-1&quot;&gt;&lt;a href=&quot;#cb5-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;module&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Acos&lt;/span&gt; (&lt;span class=&quot;fu&quot;&gt;acos&lt;/span&gt;) &lt;span class=&quot;kw&quot;&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-2&quot;&gt;&lt;a href=&quot;#cb5-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-3&quot;&gt;&lt;a href=&quot;#cb5-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Prelude&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;hiding&lt;/span&gt; (acos)&lt;/span&gt;
&lt;span id=&quot;cb5-4&quot;&gt;&lt;a href=&quot;#cb5-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Foreign.C.Types&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;CDouble&lt;/span&gt;(..))&lt;/span&gt;
&lt;span id=&quot;cb5-5&quot;&gt;&lt;a href=&quot;#cb5-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Data.Coerce&lt;/span&gt; (coerce)&lt;/span&gt;
&lt;span id=&quot;cb5-6&quot;&gt;&lt;a href=&quot;#cb5-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-7&quot;&gt;&lt;a href=&quot;#cb5-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;foreign &lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; ccall &amp;quot;math.h acos&amp;quot; c_acos :: &lt;span class=&quot;dt&quot;&gt;CDouble&lt;/span&gt; -&amp;gt; &lt;span class=&quot;dt&quot;&gt;CDouble&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-8&quot;&gt;&lt;a href=&quot;#cb5-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-9&quot;&gt;&lt;a href=&quot;#cb5-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;fu&quot;&gt;acos&lt;/span&gt;&lt;span class=&quot;ot&quot;&gt; ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Double&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Double&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-10&quot;&gt;&lt;a href=&quot;#cb5-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;fu&quot;&gt;acos&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; coerce c_acos&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
</description>
                        <pubDate>Tue, 14 May 2019 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2019-05-14-convert-cdouble-to-double</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2019-05-14-convert-cdouble-to-double.html</guid>
                </item>
        
                <item>
                        <title>Fix a torrent file encoding</title>
                        <description>&lt;p&gt;Sometimes, when you open a torrent file, the non-Latin letters in the
file names will appear garbled. Apparently, some programs write the
utf-8 name in the field &lt;code&gt;path.utf-8&lt;/code&gt; and write the field
&lt;code&gt;path&lt;/code&gt; in some other encoding.&lt;/p&gt;
&lt;p&gt;I wrote a &lt;a
href=&quot;/files/2019-05-07-fix-torrent-encoding/fix-torrent-encoding.pl&quot;&gt;small
Perl script&lt;/a&gt; that fixes such torrent files by copying the
&lt;code&gt;path.utf-8&lt;/code&gt; field into the &lt;code&gt;path&lt;/code&gt; field. To fix
the torrent file:&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;&lt;p&gt;&lt;a
href=&quot;/files/2019-05-07-fix-torrent-encoding/fix-torrent-encoding.pl&quot;&gt;Download
the script&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Make sure you have Perl installed.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Install the &lt;a
href=&quot;https://metacpan.org/pod/Bencode&quot;&gt;Bencode&lt;/a&gt; Perl module.&lt;/p&gt;
&lt;p&gt;E.g. on Fedora, you can run
&lt;code&gt;dnf install perl-Bencode.noarch&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Run&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;perl fix-torrent-encoding.pl my_broken_file.torrent new_fixed_file.torrent&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;and &lt;code&gt;new_fixed_file.torrent&lt;/code&gt; will be created.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
</description>
                        <pubDate>Tue, 07 May 2019 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2019-05-07-fix-torrent-encoding</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2019-05-07-fix-torrent-encoding.html</guid>
                </item>
        
                <item>
                        <title>Lazy validation</title>
                        <description>&lt;h2 id=&quot;why-lazy-validation&quot;&gt;Why lazy validation?&lt;/h2&gt;
&lt;p&gt;The Validation applicative functor is a convenient tool for checking
anything for errors. It’s similar to the Either type, but its
Applicative instance works differently. Whereas an Either computation
stops at the very first Left value, a Validation computation continues,
collecting all other errors so they all can be presented to the user at
once. I gave a more detailed introduction to the Validation applicative
in the article &lt;a href=&quot;/articles/2015-05-02-smarter-validation&quot;&gt;Smarter
validation&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;However, most of the time you don’t want &lt;em&gt;all&lt;/em&gt; of the errors;
you only want some reasonable number of them. Once you reach, say, 100
errors, the computation can be aborted. In particular, if we only
request a single error, then the Validation applicative should be
equivalent to the Either applicative.&lt;/p&gt;
&lt;p&gt;This is precisely the issue that I tackle in &lt;a
href=&quot;/articles/2015-05-02-smarter-validation&quot;&gt;Smarter validation&lt;/a&gt;.
In that article, I describe an implementation that maintains a bounded
list of errors internally. The maximum number of errors (“capacity”) is
specified on the type level so that it is accessible to the Applicative
instance.&lt;/p&gt;
&lt;p&gt;While that approach works, it has a few drawbacks:&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;The implementation is somewhat complicated.&lt;/li&gt;
&lt;li&gt;Keeping track of the list capacity on the type level is
inconvenient.&lt;/li&gt;
&lt;li&gt;The capacity has to be specified in advance, before running the
computation. For instance, it is not possible to get the first 10
errors, then request another 10.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;There is an alternative that is more lightweight and in the spirit of
Haskell: just make the Validation applicative produce the errors
incrementally (lazily) as the computation progresses. Then you can take
(as in Data.List.take) any number of errors you need, and the
computation will only be run until it either completes or produces the
requested number of errors.&lt;/p&gt;
&lt;h2 id=&quot;an-implementation&quot;&gt;An implementation&lt;/h2&gt;
&lt;p&gt;Here’s one way to implement a lazy Valdation applicative:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb1&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb1-1&quot;&gt;&lt;a href=&quot;#cb1-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;newtype&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Validation&lt;/span&gt; a b &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Validation&lt;/span&gt; {&lt;span class=&quot;ot&quot;&gt; runValidation ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Either&lt;/span&gt; a b }&lt;/span&gt;
&lt;span id=&quot;cb1-2&quot;&gt;&lt;a href=&quot;#cb1-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;deriving&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Functor&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-3&quot;&gt;&lt;a href=&quot;#cb1-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-4&quot;&gt;&lt;a href=&quot;#cb1-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;instance&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Monoid&lt;/span&gt; a &lt;span class=&quot;ot&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Applicative&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;Validation&lt;/span&gt; a) &lt;span class=&quot;kw&quot;&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-5&quot;&gt;&lt;a href=&quot;#cb1-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;fu&quot;&gt;pure&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Validation&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Right&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-6&quot;&gt;&lt;a href=&quot;#cb1-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  af &lt;span class=&quot;op&quot;&gt;&amp;lt;*&amp;gt;&lt;/span&gt; ax &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-7&quot;&gt;&lt;a href=&quot;#cb1-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;kw&quot;&gt;case&lt;/span&gt; runValidation af &lt;span class=&quot;kw&quot;&gt;of&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-8&quot;&gt;&lt;a href=&quot;#cb1-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;dt&quot;&gt;Right&lt;/span&gt; f &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;fmap&lt;/span&gt; f ax&lt;/span&gt;
&lt;span id=&quot;cb1-9&quot;&gt;&lt;a href=&quot;#cb1-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;dt&quot;&gt;Left&lt;/span&gt; e1 &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-10&quot;&gt;&lt;a href=&quot;#cb1-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;        &lt;span class=&quot;kw&quot;&gt;let&lt;/span&gt; e2 &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-11&quot;&gt;&lt;a href=&quot;#cb1-11&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;              &lt;span class=&quot;kw&quot;&gt;case&lt;/span&gt; runValidation ax &lt;span class=&quot;kw&quot;&gt;of&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-12&quot;&gt;&lt;a href=&quot;#cb1-12&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;                &lt;span class=&quot;dt&quot;&gt;Right&lt;/span&gt; _ &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;mempty&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-13&quot;&gt;&lt;a href=&quot;#cb1-13&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;                &lt;span class=&quot;dt&quot;&gt;Left&lt;/span&gt; e &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; e&lt;/span&gt;
&lt;span id=&quot;cb1-14&quot;&gt;&lt;a href=&quot;#cb1-14&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;        &lt;span class=&quot;kw&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Validation&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;Left&lt;/span&gt; (e1 &lt;span class=&quot;op&quot;&gt;&amp;lt;&amp;gt;&lt;/span&gt; e2))&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Notice that when the first argument of &lt;code&gt;&amp;lt;*&amp;gt;&lt;/code&gt;, namely
&lt;code&gt;af&lt;/code&gt;, is &lt;code&gt;Left&lt;/code&gt;, we return the result
&lt;code&gt;Validation (Left (e1 &amp;lt;&amp;gt; e2))&lt;/code&gt; without analyzing the
second argument, namely &lt;code&gt;ax&lt;/code&gt;, although the value
&lt;code&gt;e2&lt;/code&gt; does depend on it. But without knowing anything about
&lt;code&gt;e2&lt;/code&gt;, we can already tell that the result is a
&lt;code&gt;Left&lt;/code&gt;, and the inner value (the list of errors) starts with
&lt;code&gt;e1&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The laziness of this Validation applicative means that, for instance,
the code&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb2&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb2-1&quot;&gt;&lt;a href=&quot;#cb2-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;case&lt;/span&gt; runValidation a &lt;span class=&quot;kw&quot;&gt;of&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-2&quot;&gt;&lt;a href=&quot;#cb2-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;dt&quot;&gt;Right&lt;/span&gt; r &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; r&lt;/span&gt;
&lt;span id=&quot;cb2-3&quot;&gt;&lt;a href=&quot;#cb2-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;dt&quot;&gt;Left&lt;/span&gt; errs &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;take&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;10&lt;/span&gt; errs&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;can return the first 10 errors as soon as they are available and stop
the further evaluation of &lt;code&gt;a&lt;/code&gt;. It can even run on an infinite
computation, such as&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb3&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb3-1&quot;&gt;&lt;a href=&quot;#cb3-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;dt&quot;&gt;Validation&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;Left&lt;/span&gt; [&lt;span class=&quot;st&quot;&gt;&amp;quot;error&amp;quot;&lt;/span&gt;]) &lt;span class=&quot;op&quot;&gt;*&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-2&quot;&gt;&lt;a href=&quot;#cb3-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  fix (&lt;span class=&quot;dt&quot;&gt;Validation&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;Right&lt;/span&gt; ()) &lt;span class=&quot;op&quot;&gt;*&amp;gt;&lt;/span&gt;))&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;comparing-different-implementations&quot;&gt;Comparing different
implementations&lt;/h2&gt;
&lt;p&gt;I tested the laziness of the different implementations, including the
ones I could find on hackage. The test suite is available &lt;a
href=&quot;/files/2019-03-02-lazy-validation/test.hs&quot;&gt;here&lt;/a&gt;, and its
results are shown below:&lt;/p&gt;
&lt;table&gt;
&lt;th&gt;
&lt;/th&gt;
&lt;th&gt;
&lt;code&gt;fix (f *&amp;gt;)&lt;/code&gt;
&lt;/th&gt;
&lt;th&gt;
&lt;code&gt;f *&amp;gt; f *&amp;gt; fix (s *&amp;gt;)&lt;/code&gt;
&lt;/th&gt;
&lt;th&gt;
&lt;code&gt;f *&amp;gt; (f *&amp;gt; fix (s *&amp;gt;))&lt;/code&gt;
&lt;/th&gt;
&lt;th&gt;
&lt;code&gt;f *&amp;gt; fix (s *&amp;gt;)&lt;/code&gt;
&lt;/th&gt;
&lt;tr&gt;
&lt;th&gt;
transformers-0.5.5.0
&lt;/th&gt;
&lt;td&gt;
&lt;span class=&quot;result failure&quot;&gt;✗&lt;/span&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;span class=&quot;result failure&quot;&gt;✗&lt;/span&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;span class=&quot;result failure&quot;&gt;✗&lt;/span&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;span class=&quot;result failure&quot;&gt;✗&lt;/span&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;th&gt;
transformers-0.5.5.0 (patched)
&lt;/th&gt;
&lt;td&gt;
&lt;span class=&quot;result success&quot;&gt;✓&lt;/span&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;span class=&quot;result success&quot;&gt;✓&lt;/span&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;span class=&quot;result success&quot;&gt;✓&lt;/span&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;span class=&quot;result success&quot;&gt;✓&lt;/span&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;th&gt;
either-5.0.1
&lt;/th&gt;
&lt;td&gt;
&lt;span class=&quot;result success&quot;&gt;✓&lt;/span&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;span class=&quot;result failure&quot;&gt;✗&lt;/span&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;span class=&quot;result success&quot;&gt;✓&lt;/span&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;span class=&quot;result failure&quot;&gt;✗&lt;/span&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;th&gt;
validation-1
&lt;/th&gt;
&lt;td&gt;
&lt;span class=&quot;result success&quot;&gt;✓&lt;/span&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;span class=&quot;result failure&quot;&gt;✗&lt;/span&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;span class=&quot;result success&quot;&gt;✓&lt;/span&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;span class=&quot;result failure&quot;&gt;✗&lt;/span&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;th&gt;
This article
&lt;/th&gt;
&lt;td&gt;
&lt;span class=&quot;result success&quot;&gt;✓&lt;/span&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;span class=&quot;result success&quot;&gt;✓&lt;/span&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;span class=&quot;result success&quot;&gt;✓&lt;/span&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;span class=&quot;result success&quot;&gt;✓&lt;/span&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;th&gt;
Smarter (cap = 1)
&lt;/th&gt;
&lt;td&gt;
&lt;span class=&quot;result success&quot;&gt;✓&lt;/span&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;span class=&quot;result success&quot;&gt;✓&lt;/span&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;span class=&quot;result success&quot;&gt;✓&lt;/span&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;span class=&quot;result success&quot;&gt;✓&lt;/span&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;th&gt;
Smarter (cap = 2)
&lt;/th&gt;
&lt;td&gt;
&lt;span class=&quot;result success&quot;&gt;✓&lt;/span&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;span class=&quot;result success&quot;&gt;✓&lt;/span&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;span class=&quot;result success&quot;&gt;✓&lt;/span&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;span class=&quot;result failure&quot;&gt;✗&lt;/span&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;p&gt;Each test attempts to extract &lt;strong&gt;the first error&lt;/strong&gt; from
an infinite Validation computation. These computations are:&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;fix (f *&amp;gt;)&lt;/code&gt;, an infinite stream of failures.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;fix (f *&amp;gt;)&lt;/code&gt; simply means
&lt;code&gt;f *&amp;gt; (f *&amp;gt; (f *&amp;gt; ... ))&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;f *&amp;gt; f *&amp;gt; fix (s *&amp;gt;)&lt;/code&gt;, two failures followed
by an infinite stream of successes. Since &lt;code&gt;*&amp;gt;&lt;/code&gt; is defined
as &lt;code&gt;infixl&lt;/code&gt;, this really means
&lt;code&gt;(f *&amp;gt; f) *&amp;gt; fix (s *&amp;gt;)&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;f *&amp;gt; (f *&amp;gt; fix (s *&amp;gt;))&lt;/code&gt;, again two failures
followed by an infinite stream of successes, but this time the grouping
is different. The Applicative laws say that this shouldn’t be any
different from the previous test, but the table shows that they do
differ in practice.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;f *&amp;gt; fix (s *&amp;gt;)&lt;/code&gt;, a single failure followed by
an infinite stream of successes.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The implementations tested are:&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;&lt;a
href=&quot;https://hackage.haskell.org/package/transformers-0.5.5.0/docs/Control-Applicative-Lift.html#g:2&quot;&gt;The
Errors type from transformers-0.5.5.0&lt;/a&gt;, based on the Lift
applicative.&lt;/li&gt;
&lt;li&gt;The same Errors type, but with a patched Applicative Lift instance
(see below).&lt;/li&gt;
&lt;li&gt;&lt;a
href=&quot;https://hackage.haskell.org/package/either-5.0.1/docs/Data-Either-Validation.html&quot;&gt;The
Validation type from either-5.0.1&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a
href=&quot;https://hackage.haskell.org/package/validation-1/docs/Data-Validation.html&quot;&gt;The
Validation type from validation-1&lt;/a&gt;, which, from what I can tell, is
more or less the same code as in either-5.0.1.&lt;/li&gt;
&lt;li&gt;The Validation type defined &lt;a href=&quot;#an-implementation&quot;&gt;above in
this article&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;SmartValidation&lt;/code&gt; type defined in &lt;a
href=&quot;/articles/2015-05-02-smarter-validation&quot;&gt;the earlier article&lt;/a&gt;,
configured to retain no more than 1 error.&lt;/li&gt;
&lt;li&gt;The same &lt;code&gt;SmartValidation&lt;/code&gt; type, but configured to retain
no more than 2 errors.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;So what conclusions can we draw from this experiment?&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;&lt;p&gt;The Errors type from transformers is usually my go-to
implementation, since it is available in the de-facto standard package
and therefore doesn’t incur any extra dependencies. As the table shows,
it doesn’t pass any tests, so it’s not lazy at all. This is because the
current Applicative Lift instance assumes that both sides of
&lt;code&gt;&amp;lt;*&amp;gt;&lt;/code&gt; are evaluated:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb4&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb4-1&quot;&gt;&lt;a href=&quot;#cb4-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;instance&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;Applicative&lt;/span&gt; f) &lt;span class=&quot;ot&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Applicative&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;Lift&lt;/span&gt; f) &lt;span class=&quot;kw&quot;&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-2&quot;&gt;&lt;a href=&quot;#cb4-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;fu&quot;&gt;pure&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Pure&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-3&quot;&gt;&lt;a href=&quot;#cb4-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;dt&quot;&gt;Pure&lt;/span&gt; f &lt;span class=&quot;op&quot;&gt;&amp;lt;*&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Pure&lt;/span&gt; x &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Pure&lt;/span&gt; (f x)&lt;/span&gt;
&lt;span id=&quot;cb4-4&quot;&gt;&lt;a href=&quot;#cb4-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;dt&quot;&gt;Pure&lt;/span&gt; f &lt;span class=&quot;op&quot;&gt;&amp;lt;*&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Other&lt;/span&gt; y &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Other&lt;/span&gt; (f &lt;span class=&quot;op&quot;&gt;&amp;lt;$&amp;gt;&lt;/span&gt; y)&lt;/span&gt;
&lt;span id=&quot;cb4-5&quot;&gt;&lt;a href=&quot;#cb4-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;dt&quot;&gt;Other&lt;/span&gt; f &lt;span class=&quot;op&quot;&gt;&amp;lt;*&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Pure&lt;/span&gt; x &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Other&lt;/span&gt; ((&lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; x) &lt;span class=&quot;op&quot;&gt;&amp;lt;$&amp;gt;&lt;/span&gt; f)&lt;/span&gt;
&lt;span id=&quot;cb4-6&quot;&gt;&lt;a href=&quot;#cb4-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;dt&quot;&gt;Other&lt;/span&gt; f &lt;span class=&quot;op&quot;&gt;&amp;lt;*&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Other&lt;/span&gt; y &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Other&lt;/span&gt; (f &lt;span class=&quot;op&quot;&gt;&amp;lt;*&amp;gt;&lt;/span&gt; y)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;However, this instance can be easily made lazy:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb5&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb5-1&quot;&gt;&lt;a href=&quot;#cb5-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;instance&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;Applicative&lt;/span&gt; f) &lt;span class=&quot;ot&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Applicative&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;Lift&lt;/span&gt; f) &lt;span class=&quot;kw&quot;&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-2&quot;&gt;&lt;a href=&quot;#cb5-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;fu&quot;&gt;pure&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Pure&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-3&quot;&gt;&lt;a href=&quot;#cb5-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;dt&quot;&gt;Pure&lt;/span&gt; f &lt;span class=&quot;op&quot;&gt;&amp;lt;*&amp;gt;&lt;/span&gt; ax &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; f &lt;span class=&quot;op&quot;&gt;&amp;lt;$&amp;gt;&lt;/span&gt; ax&lt;/span&gt;
&lt;span id=&quot;cb5-4&quot;&gt;&lt;a href=&quot;#cb5-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;dt&quot;&gt;Other&lt;/span&gt; f &lt;span class=&quot;op&quot;&gt;&amp;lt;*&amp;gt;&lt;/span&gt; ax &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-5&quot;&gt;&lt;a href=&quot;#cb5-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;dt&quot;&gt;Other&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; f &lt;span class=&quot;op&quot;&gt;&amp;lt;*&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-6&quot;&gt;&lt;a href=&quot;#cb5-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;        (&lt;span class=&quot;kw&quot;&gt;case&lt;/span&gt; ax &lt;span class=&quot;kw&quot;&gt;of&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-7&quot;&gt;&lt;a href=&quot;#cb5-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;          &lt;span class=&quot;dt&quot;&gt;Pure&lt;/span&gt; x &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;pure&lt;/span&gt; x&lt;/span&gt;
&lt;span id=&quot;cb5-8&quot;&gt;&lt;a href=&quot;#cb5-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;          &lt;span class=&quot;dt&quot;&gt;Other&lt;/span&gt; y &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; y&lt;/span&gt;
&lt;span id=&quot;cb5-9&quot;&gt;&lt;a href=&quot;#cb5-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;        )&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This is the “transformers-0.5.5.0 (patched)” entry in the table. I
also &lt;a href=&quot;https://hub.darcs.net/ross/transformers/issue/68&quot;&gt;opened
an issue&lt;/a&gt; to put the lazy version into transformers, and Ross
Paterson promptly &lt;a
href=&quot;https://hub.darcs.net/ross/transformers/patch/c00d7de1dbb50b88d6c9cac5e66507cdd80f4cb6&quot;&gt;made
the change&lt;/a&gt;, so &lt;strong&gt;starting from the next version, transformers
will provide a lazy Validation applicative&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The either-5.0.1 and validation-1 versions of Validation appear
to be identical, and they pass the same set of tests. For practical
purposes they can be considered lazy, although they do fail on some edge
cases. These failures, however, are not accidental: they are a
consequence of relying only on the Semigroup instance of errors, not
Monoid. On the one hand, this is a good property, because it makes it
less likely that you’ll end up with &lt;code&gt;Failure mempty&lt;/code&gt;.&lt;/p&gt;
&lt;figure&gt;
&lt;p&gt;&lt;img src=&quot;/img/errortheoperationcompletedsuccessfully.png&quot; /&gt;&lt;/p&gt;
&lt;/figure&gt;
&lt;p&gt;On the other hand, because there’s no &lt;code&gt;mempty&lt;/code&gt;, the
implementation of &lt;code&gt;&amp;lt;*&amp;gt;&lt;/code&gt; has a “latency” of 1 error: in
order to emit an error, it needs to see not only this error but also the
next one (or reach the end of the computation to find out that it was
the last one).&lt;/p&gt;
&lt;p&gt;Let’s see why this is the case. Say you see an error &lt;code&gt;e&lt;/code&gt;.
If the error type is a Monoid, you can emit
&lt;code&gt;e &amp;lt;&amp;gt; thunk&lt;/code&gt;, where &lt;code&gt;thunk&lt;/code&gt; will evaluate
either to &lt;code&gt;e2 &amp;lt;&amp;gt; thunk2&lt;/code&gt; or &lt;code&gt;mempty&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Now suppose the error type is a Semigroup but not a Monoid. Say you
emitted &lt;code&gt;e &amp;lt;&amp;gt; thunk&lt;/code&gt; when you first saw it, but then
the computation ended without any additional errors. What should the
thunk evaluate to?&lt;/p&gt;
&lt;p&gt;To work around that issue, wait until you see either the next error,
&lt;code&gt;e2&lt;/code&gt;, or the end of the computation. In the first case, emit
&lt;code&gt;e &amp;lt;&amp;gt; thunk&lt;/code&gt;, knowing that the thunk can at least
evaluate to &lt;code&gt;e2&lt;/code&gt;. In the second case, simply return
&lt;code&gt;e&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;To summarize, either-5.0.1 and validation-1 are not perfectly lazy,
but they come pretty close and have other advantages.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The &lt;a href=&quot;/articles/2015-05-02-smarter-validation&quot;&gt;“smart
validation”&lt;/a&gt; applicative, when restricted to produce a single error,
does pass all the tests. But it’s not &lt;em&gt;really&lt;/em&gt; lazy—we just
cheated when we told it in advance how many errors we were going to
request. When we told it to hold no more than 2 errors and then gave it
an infinite stream with only one error, it never returned that
error.&lt;/p&gt;
&lt;p&gt;That said, notice that “Smarter (cap = 2)” passed the
&lt;code&gt;f *&amp;gt; f *&amp;gt; fix (s *&amp;gt;)&lt;/code&gt; test, which either-5.0.1 and
validation-1 did not pass. Because the smart validation functor is
continuation-based, it doesn’t care how the original computation was
grouped.&lt;/p&gt;
&lt;p&gt;This has also practical implications regarding performance. The
“smart validation” approach has linear complexity no matter how the
computation is oragnized, whereas the more straightforward approaches
have quadratic worst-case complexity.&lt;/p&gt;
&lt;p&gt;In the following test, we requested not the &lt;em&gt;first&lt;/em&gt;, but the
&lt;em&gt;last&lt;/em&gt; error from a long left-nested stream of errors. The test
passes only if it finishes in under 100ms.&lt;/p&gt;
&lt;table&gt;
&lt;th&gt;
&lt;/th&gt;
&lt;th&gt;
&lt;p&gt;&lt;code&gt;iterate (*&amp;gt; f) f !! 10000&lt;/code&gt;&lt;/p&gt;
&lt;/th&gt;
&lt;tr&gt;
&lt;th&gt;
&lt;p&gt;transformers-0.5.5.0&lt;/p&gt;
&lt;/th&gt;
&lt;td&gt;
&lt;p&gt;&lt;span class=&quot;result failure&quot;&gt;✗&lt;/span&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;th&gt;
&lt;p&gt;transformers-0.5.5.0 (patched)&lt;/p&gt;
&lt;/th&gt;
&lt;td&gt;
&lt;p&gt;&lt;span class=&quot;result failure&quot;&gt;✗&lt;/span&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;th&gt;
&lt;p&gt;either-5.0.1&lt;/p&gt;
&lt;/th&gt;
&lt;td&gt;
&lt;p&gt;&lt;span class=&quot;result failure&quot;&gt;✗&lt;/span&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;th&gt;
&lt;p&gt;validation-1&lt;/p&gt;
&lt;/th&gt;
&lt;td&gt;
&lt;p&gt;&lt;span class=&quot;result failure&quot;&gt;✗&lt;/span&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;th&gt;
&lt;p&gt;This article&lt;/p&gt;
&lt;/th&gt;
&lt;td&gt;
&lt;p&gt;&lt;span class=&quot;result failure&quot;&gt;✗&lt;/span&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;th&gt;
&lt;p&gt;Smarter (cap = 1)&lt;/p&gt;
&lt;/th&gt;
&lt;td&gt;
&lt;p&gt;&lt;span class=&quot;result success&quot;&gt;✓&lt;/span&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;th&gt;
&lt;p&gt;Smarter (cap = 2)&lt;/p&gt;
&lt;/th&gt;
&lt;td&gt;
&lt;p&gt;&lt;span class=&quot;result success&quot;&gt;✓&lt;/span&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;&lt;/li&gt;
&lt;/ol&gt;
</description>
                        <pubDate>Sat, 02 Mar 2019 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2019-03-02-lazy-validation-applicative</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2019-03-02-lazy-validation-applicative.html</guid>
                </item>
        
                <item>
                        <title>Surprises of the Haskell module system (part 2)</title>
                        <description>&lt;p&gt;It’s been 6 years since I published &lt;a
href=&quot;/articles/2012-12-25-haskell-module-system-p1&quot;&gt;Surprises of the
Haskell module system (part 1)&lt;/a&gt;, so I thought it was time to follow
through on the implicit promise and publish part 2.&lt;/p&gt;
&lt;h2 id=&quot;exporting-constructors-without-data-type&quot;&gt;Exporting constructors
without data type&lt;/h2&gt;
&lt;p&gt;Is it possible to export a data constructor without exporting its
parent data type? To be clear, there’s probably no good reason to want
to do that, but it’s a fun puzzle, and we’ll learn something while
trying to solve it.&lt;/p&gt;
&lt;p&gt;Surprisingly, the answer depends on how our constructor and type are
named. First, consider the case when they are named differently, as
in&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb1&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb1-1&quot;&gt;&lt;a href=&quot;#cb1-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;T&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;C&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The naive attempt&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb2&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb2-1&quot;&gt;&lt;a href=&quot;#cb2-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;module&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;M&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;C&lt;/span&gt;) &lt;span class=&quot;kw&quot;&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-2&quot;&gt;&lt;a href=&quot;#cb2-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;T&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;C&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;does not work. The &lt;a
href=&quot;http://www.haskell.org/onlinereport/haskell2010/haskellch5.html&quot;&gt;Haskell
2010&lt;/a&gt; standard says this about data types in the export list:&lt;/p&gt;
&lt;blockquote&gt;
An algebraic datatype &lt;span class=&quot;cmmi-10&quot;&gt;T&lt;/span&gt;
&lt;a id=&quot;dx11-100008&quot;&gt;&lt;/a&gt;declared by a &lt;span class=&quot;pcrr7t-&quot;&gt;data&lt;/span&gt;
or &lt;span class=&quot;pcrr7t-&quot;&gt;newtype&lt;/span&gt; declaration may be named in one
of three ways:
&lt;ul class=&quot;itemize1&quot;&gt;
&lt;li class=&quot;itemize&quot;&gt;
The form &lt;span class=&quot;cmmi-10&quot;&gt;T&lt;/span&gt; names the type &lt;span
class=&quot;ptmri7t-&quot;&gt;but not the constructors or field names&lt;/span&gt;. The
ability to export a type without its constructors allows the
construction of abstract datatypes (see Section 5.8).
&lt;/li&gt;
&lt;li class=&quot;itemize&quot;&gt;
The form &lt;span class=&quot;cmmi-10&quot;&gt;T&lt;/span&gt;&lt;span
class=&quot;pcrr7t-&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;cmmi-10&quot;&gt;c&lt;/span&gt;&lt;sub&gt;&lt;span
class=&quot;cmr-7&quot;&gt;1&lt;/span&gt;&lt;/sub&gt;&lt;span class=&quot;pcrr7t-&quot;&gt;,&lt;/span&gt;&lt;span
class=&quot;cmmi-10&quot;&gt;…&lt;/span&gt;&lt;span class=&quot;pcrr7t-&quot;&gt;,&lt;/span&gt;&lt;span
class=&quot;cmmi-10&quot;&gt;c&lt;/span&gt;&lt;sub&gt;&lt;span class=&quot;cmmi-7&quot;&gt;n&lt;/span&gt;&lt;/sub&gt;&lt;span
class=&quot;pcrr7t-&quot;&gt;)&lt;/span&gt;, names the type and some or all of its
constructors and field names.
&lt;/li&gt;
&lt;li class=&quot;itemize&quot;&gt;
The abbreviated form &lt;span class=&quot;cmmi-10&quot;&gt;T&lt;/span&gt;&lt;span
class=&quot;pcrr7t-&quot;&gt;(..)&lt;/span&gt; names the type and all its constructors and
field names that are currently in scope (whether qualified or not).
&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;Therefore, there seems to be no way to export a constructor without
exporting its parent type at the same time. But here’s the trick. First,
let’s move the data type definition from &lt;code&gt;M&lt;/code&gt; to a different
module, &lt;code&gt;Internal&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb3&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb3-1&quot;&gt;&lt;a href=&quot;#cb3-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;module&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Internal&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-2&quot;&gt;&lt;a href=&quot;#cb3-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;T&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;C&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Then, in our module &lt;code&gt;M&lt;/code&gt;, import &lt;code&gt;Internal&lt;/code&gt; like
this:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb4&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb4-1&quot;&gt;&lt;a href=&quot;#cb4-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;module&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;M&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-2&quot;&gt;&lt;a href=&quot;#cb4-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Internal&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;hiding&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;T&lt;/span&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This will import &lt;code&gt;C&lt;/code&gt; but not &lt;code&gt;T&lt;/code&gt;. Here’s
Haskell 2010 on the semantics of &lt;code&gt;hiding&lt;/code&gt; lists:&lt;/p&gt;
&lt;blockquote&gt;
Entities can be excluded by using the form &lt;span
class=&quot;pcrr7t-&quot;&gt;hiding(&lt;/span&gt;&lt;span
class=&quot;cmmi-10&quot;&gt;import&lt;/span&gt;&lt;sub&gt;&lt;span
class=&quot;cmr-7&quot;&gt;1&lt;/span&gt;&lt;/sub&gt;&lt;span class=&quot;cmmi-10&quot;&gt; &lt;/span&gt;&lt;span
class=&quot;pcrr7t-&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;cmmi-10&quot;&gt; &lt;/span&gt;&lt;span
class=&quot;cmmi-10&quot;&gt;…&lt;/span&gt;&lt;span class=&quot;cmmi-10&quot;&gt; &lt;/span&gt;&lt;span
class=&quot;pcrr7t-&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;cmmi-10&quot;&gt; import&lt;/span&gt;&lt;sub&gt;&lt;span
class=&quot;cmmi-7&quot;&gt;n&lt;/span&gt;&lt;/sub&gt; &lt;span
class=&quot;pcrr7t-&quot;&gt;)&lt;/span&gt;,&lt;a id=&quot;dx11-102005&quot;&gt;&lt;/a&gt; which specifies that
all entities exported by the named module should be imported except for
those named in the list. Data constructors may be named directly in
hiding lists without being prefixed by the associated type. Thus, in
&lt;div class=&quot;quote&quot;&gt;
&lt;div id=&quot;verbatim-90&quot; class=&quot;verbatim&quot;&gt;
&lt;p&gt;  import M hiding (C)&lt;/p&gt;
&lt;/div&gt;
&lt;p class=&quot;noindent&quot;&gt;
&lt;/p&gt;
&lt;/div&gt;
&lt;p class=&quot;noindent&quot;&gt;
any constructor, class, or type named &lt;span class=&quot;pcrr7t-&quot;&gt;C&lt;/span&gt; is
excluded. In contrast, using &lt;span class=&quot;pcrr7t-&quot;&gt;C&lt;/span&gt; in an import
list names only a class or type.
&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;So now, within module &lt;code&gt;M&lt;/code&gt;, we have only &lt;code&gt;C&lt;/code&gt; in
scope but not &lt;code&gt;T&lt;/code&gt;. But &lt;code&gt;M&lt;/code&gt; does not
&lt;em&gt;export&lt;/em&gt; any of them yet, and it seems like we need
&lt;code&gt;T&lt;/code&gt; in scope in order to add &lt;code&gt;C&lt;/code&gt; to the export
list.&lt;/p&gt;
&lt;p&gt;Here we use a second trick: instead of naming &lt;code&gt;C&lt;/code&gt;
specifically, we export our &lt;code&gt;Internal&lt;/code&gt; module as a whole:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb5&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb5-1&quot;&gt;&lt;a href=&quot;#cb5-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;module&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;M&lt;/span&gt; (&lt;span class=&quot;kw&quot;&gt;module&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Internal&lt;/span&gt;) &lt;span class=&quot;kw&quot;&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-2&quot;&gt;&lt;a href=&quot;#cb5-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Internal&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;hiding&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;T&lt;/span&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;And this achieves the desired result: &lt;code&gt;M&lt;/code&gt; now exports the
data constructor &lt;code&gt;C&lt;/code&gt; but not the data type &lt;code&gt;T&lt;/code&gt;.
See &lt;a href=&quot;/articles/2012-12-25-haskell-module-system-p1&quot;&gt;Part 1&lt;/a&gt;
for more discussion of module exports.&lt;/p&gt;
&lt;p&gt;This all works because the data type and its constructor are named
differently. If we have&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb6&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb6-1&quot;&gt;&lt;a href=&quot;#cb6-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;T&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;T&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;this won’t work, because&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb7&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb7-1&quot;&gt;&lt;a href=&quot;#cb7-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Internal&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;hiding&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;T&lt;/span&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;will hide both the data type and the data constructor. I actually
don’t know a way to export the constructor &lt;code&gt;T&lt;/code&gt; without the
type &lt;code&gt;T&lt;/code&gt;; if you do, please let me know.&lt;/p&gt;
&lt;h2 id=&quot;exporting-fields-without-constructor&quot;&gt;Exporting fields without
constructor&lt;/h2&gt;
&lt;p&gt;A similar question is that of exporting a field name without
exporting its parent constructor, as in&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb8&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb8-1&quot;&gt;&lt;a href=&quot;#cb8-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;module&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;M&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;T&lt;/span&gt;, field) &lt;span class=&quot;kw&quot;&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb8-2&quot;&gt;&lt;a href=&quot;#cb8-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;T&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;C&lt;/span&gt; {&lt;span class=&quot;ot&quot;&gt; field ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Bool&lt;/span&gt; }&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The above code works. But what does it &lt;em&gt;mean&lt;/em&gt;? Field names can
be used as functions (e.g. &lt;code&gt;field :: T -&amp;gt; Bool&lt;/code&gt;), but they
can also be used in the record construction
(&lt;code&gt;C { field = True }&lt;/code&gt;) and record update
(&lt;code&gt;x { field = True }&lt;/code&gt;) syntaxes.&lt;/p&gt;
&lt;p&gt;Since we don’t export the data constructor, clearly record
construction won’t work. But what about record update? Does
&lt;code&gt;field&lt;/code&gt; lose its magic and become a simple function when
exported this way—either because it wasn’t exported as
&lt;code&gt;T(field)&lt;/code&gt;, or because the data constructor is not in scope?
The answer is no, it is still a valid field name, and
&lt;code&gt;x { field = True }&lt;/code&gt; still works. Here’s Haskell 2010:&lt;/p&gt;
&lt;blockquote&gt;
It makes no difference to an importing module how an entity was
exported. For example, a field name &lt;span class=&quot;pcrr7t-&quot;&gt;f&lt;/span&gt; from
data type &lt;span class=&quot;pcrr7t-&quot;&gt;T&lt;/span&gt; may be exported individually
(&lt;span class=&quot;pcrr7t-&quot;&gt;f&lt;/span&gt;, item (1) above); or as an
explicitly-named member of its data type (&lt;span
class=&quot;pcrr7t-&quot;&gt;T(f)&lt;/span&gt;, item (2)); or as an implicitly-named member
(&lt;span class=&quot;pcrr7t-&quot;&gt;T(..)&lt;/span&gt;, item(2)); or by exporting an entire
module (&lt;span class=&quot;pcrr7t-&quot;&gt;module&lt;/span&gt;&lt;span
class=&quot;pcrr7t-&quot;&gt; M&lt;/span&gt;, item (5)).
&lt;/blockquote&gt;
&lt;p&gt;And there’s no requirement that the constructor be in scope in order
to use the record update syntax—even though its desugaring would require
all of the constructors to be in scope.&lt;/p&gt;
&lt;p&gt;Some authors use this to their advantage: for instance, &lt;a
href=&quot;https://www.yesodweb.com/book/settings-types&quot;&gt;Michael Snoyman
suggests exporting fields but not constructors for settings
types&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;But more often than not, we want the opposite: to make the type
abstract and export a getter for it. If you think the module
&lt;code&gt;M&lt;/code&gt; above exports an abstract type &lt;code&gt;T&lt;/code&gt; and a
function &lt;code&gt;field :: T -&amp;gt; Bool&lt;/code&gt;, then you may believe you
are free to change the implementation of &lt;code&gt;T&lt;/code&gt; without your
users noticing. So in the next version you may change &lt;code&gt;T&lt;/code&gt;
to&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb9&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb9-1&quot;&gt;&lt;a href=&quot;#cb9-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;module&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;M&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;T&lt;/span&gt;, field) &lt;span class=&quot;kw&quot;&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb9-2&quot;&gt;&lt;a href=&quot;#cb9-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;T&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;C&lt;/span&gt; {&lt;span class=&quot;ot&quot;&gt; items ::&lt;/span&gt; [&lt;span class=&quot;dt&quot;&gt;Int&lt;/span&gt;] }&lt;/span&gt;
&lt;span id=&quot;cb9-3&quot;&gt;&lt;a href=&quot;#cb9-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;field ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;T&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Bool&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb9-4&quot;&gt;&lt;a href=&quot;#cb9-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;field &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;not&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;null&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt; items&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This new module still exports a type &lt;code&gt;T&lt;/code&gt; and a function
&lt;code&gt;field :: T -&amp;gt; Bool&lt;/code&gt;, but that function is no longer a
record field. If someone was using &lt;code&gt;field&lt;/code&gt; in a record
update, &lt;code&gt;x { field = True }&lt;/code&gt;, their code is going to
break.&lt;/p&gt;
&lt;p&gt;There’s no way to export a field as a plain function or otherwise
strip it of its magic. You can either define a getter yourself, as
in&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb10&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb10-1&quot;&gt;&lt;a href=&quot;#cb10-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;T&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;C&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Bool&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb10-2&quot;&gt;&lt;a href=&quot;#cb10-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;field ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;T&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Bool&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb10-3&quot;&gt;&lt;a href=&quot;#cb10-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;field &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; \&lt;span class=&quot;kw&quot;&gt;case&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb10-4&quot;&gt;&lt;a href=&quot;#cb10-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;dt&quot;&gt;C&lt;/span&gt; a &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; a&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;or create a copy of a field, as in&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb11&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb11-1&quot;&gt;&lt;a href=&quot;#cb11-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;T&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;C&lt;/span&gt; {&lt;span class=&quot;ot&quot;&gt; _field ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Bool&lt;/span&gt; }&lt;/span&gt;
&lt;span id=&quot;cb11-2&quot;&gt;&lt;a href=&quot;#cb11-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;field ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;T&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Bool&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb11-3&quot;&gt;&lt;a href=&quot;#cb11-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;field &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; _field&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;hidden-types-and-type-synonyms&quot;&gt;Hidden types and type
synonyms&lt;/h2&gt;
&lt;p&gt;Consider this example:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb12&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb12-1&quot;&gt;&lt;a href=&quot;#cb12-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;module&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;M&lt;/span&gt; (x) &lt;span class=&quot;kw&quot;&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb12-2&quot;&gt;&lt;a href=&quot;#cb12-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb12-3&quot;&gt;&lt;a href=&quot;#cb12-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;T&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Int&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb12-4&quot;&gt;&lt;a href=&quot;#cb12-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb12-5&quot;&gt;&lt;a href=&quot;#cb12-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;x ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;T&lt;/span&gt;  &lt;/span&gt;
&lt;span id=&quot;cb12-6&quot;&gt;&lt;a href=&quot;#cb12-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;x &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt; &lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;What type does &lt;code&gt;x&lt;/code&gt; have in a module that imports
&lt;code&gt;M&lt;/code&gt;? On the one hand, &lt;code&gt;T&lt;/code&gt; is &lt;code&gt;Int&lt;/code&gt;, so
&lt;code&gt;x :: Int&lt;/code&gt;. On the other hand, since &lt;code&gt;T&lt;/code&gt; is not in
scope, there’s no way to know that &lt;code&gt;T = Int&lt;/code&gt;, so it might
seem that &lt;code&gt;x&lt;/code&gt; is now an opaque value of some abstract type
&lt;code&gt;T&lt;/code&gt; that we know nothing about. In fact, the former view is
correct and the latter isn’t.&lt;/p&gt;
&lt;blockquote&gt;
The type of an exported entity is unaffected by non-exported type
synonyms. For example, in
&lt;div class=&quot;quote&quot;&gt;
&lt;div id=&quot;verbatim-101&quot; class=&quot;verbatim&quot;&gt;
&lt;p&gt;  module M(x) where  &lt;br&gt;    type T = Int  &lt;br&gt;    x :: T
 &lt;br&gt;    x = 1&lt;/p&gt;
&lt;/div&gt;
&lt;p class=&quot;noindent&quot;&gt;
&lt;/p&gt;
&lt;/div&gt;
&lt;p class=&quot;noindent&quot;&gt;
the type of &lt;span class=&quot;pcrr7t-&quot;&gt;x&lt;/span&gt; is both &lt;span
class=&quot;pcrr7t-&quot;&gt;T&lt;/span&gt; and &lt;span class=&quot;pcrr7t-&quot;&gt;Int&lt;/span&gt;; these are
interchangeable even when &lt;span class=&quot;pcrr7t-&quot;&gt;T&lt;/span&gt; is not in
scope. That is, the definition of &lt;span class=&quot;pcrr7t-&quot;&gt;T&lt;/span&gt; is
available to any module that encounters it whether or not the name &lt;span
class=&quot;pcrr7t-&quot;&gt;T&lt;/span&gt; is in scope. The only reason to export &lt;span
class=&quot;pcrr7t-&quot;&gt;T&lt;/span&gt; is to allow other modules to refer it by name;
the type checker finds the definition of &lt;span class=&quot;pcrr7t-&quot;&gt;T&lt;/span&gt;
if needed whether or not it is exported.
&lt;/blockquote&gt;
&lt;p&gt;Similarly, you may wonder what does it mean to export a function but
hide some of the types that are part of its signature. Here’s what
Haskell 2010 has to say about that:&lt;/p&gt;
&lt;blockquote&gt;
[E]ntities that the compiler requires for type checking or other compile
time analysis need not be imported if they are not mentioned by name.
The Haskell compilation system is responsible for finding any
information needed for compilation without the help of the programmer.
That is, the import of a variable &lt;span class=&quot;pcrr7t-&quot;&gt;x&lt;/span&gt; does
not require that the datatypes and classes in the signature of &lt;span
class=&quot;pcrr7t-&quot;&gt;x&lt;/span&gt; be brought into the module along with &lt;span
class=&quot;pcrr7t-&quot;&gt;x&lt;/span&gt; unless these entities are referenced by name in
the user program. The Haskell system silently imports any information
that must accompany an entity for type checking or any other purposes.
Such entities need not even be explicitly exported: the following
program is valid even though &lt;span class=&quot;pcrr7t-&quot;&gt;T&lt;/span&gt; does not
escape &lt;span class=&quot;pcrr7t-&quot;&gt;M1&lt;/span&gt;:
&lt;div class=&quot;quote&quot;&gt;
&lt;div id=&quot;verbatim-100&quot; class=&quot;verbatim&quot;&gt;
&lt;p&gt;  module M1(x) where  &lt;br&gt;    data T = T  &lt;br&gt;    x = T  &lt;br&gt;
 &lt;br&gt;  module M2 where  &lt;br&gt;    import M1(x)  &lt;br&gt;    y = x&lt;/p&gt;
&lt;/div&gt;
&lt;p class=&quot;noindent&quot;&gt;
&lt;/p&gt;
&lt;/div&gt;
&lt;p class=&quot;noindent&quot;&gt;
In this example, there is no way to supply an explicit type signature
for &lt;span class=&quot;pcrr7t-&quot;&gt;y&lt;/span&gt; since &lt;span class=&quot;pcrr7t-&quot;&gt;T&lt;/span&gt;
is not in scope. Whether or not &lt;span class=&quot;pcrr7t-&quot;&gt;T&lt;/span&gt; is
explicitly exported, module &lt;span class=&quot;pcrr7t-&quot;&gt;M2&lt;/span&gt; knows enough
about &lt;span class=&quot;pcrr7t-&quot;&gt;T&lt;/span&gt; to correctly type check the
program.
&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;self-exporting-module&quot;&gt;Self-exporting module&lt;/h2&gt;
&lt;p&gt;By default—when no export list is present in a module—all values,
types and classes defined in the module are exported, but not those that
are imported. With an explicit export list, we can export a mix of
entities from the module itself and the modules it imports. But now you
have to explicitly list everything defined in the current module and
remember to update the list when you define a new function or type. Or
do you?&lt;/p&gt;
&lt;p&gt;There’s a nice trick to have an explicit export list and
automatically export everything from the current module at the same
time: just let the module export itself.&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb13&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb13-1&quot;&gt;&lt;a href=&quot;#cb13-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;co&quot;&gt;-- exports x, y, and z&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb13-2&quot;&gt;&lt;a href=&quot;#cb13-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;module&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;M&lt;/span&gt; (&lt;span class=&quot;kw&quot;&gt;module&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;M&lt;/span&gt;, Foo.x, Bar.y) &lt;span class=&quot;kw&quot;&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb13-3&quot;&gt;&lt;a href=&quot;#cb13-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb13-4&quot;&gt;&lt;a href=&quot;#cb13-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Foo&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb13-5&quot;&gt;&lt;a href=&quot;#cb13-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Bar&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb13-6&quot;&gt;&lt;a href=&quot;#cb13-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb13-7&quot;&gt;&lt;a href=&quot;#cb13-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;z &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;undefined&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Thanks to the clear semantics of module exports (which we discussed
in &lt;a href=&quot;/articles/2012-12-25-haskell-module-system-p1&quot;&gt;Part 1&lt;/a&gt;),
self-exporting is well-defined and doesn’t involve any recursion.&lt;/p&gt;
</description>
                        <pubDate>Sat, 26 Jan 2019 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2019-01-26-haskell-module-system-p2</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2019-01-26-haskell-module-system-p2.html</guid>
                </item>
        
                <item>
                        <title>A better noise gate</title>
                        <description>&lt;p&gt;A &lt;em&gt;noise gate&lt;/em&gt; is a type of sound effect. It detects the parts
of the audio signal with very low volume, where nothing is happening
apart from the background noise, and either reduces the volume further
or silences it completely. It doesn’t remove the noise from under the
speech—that’s called &lt;em&gt;noise reduction&lt;/em&gt;—but it removes the noise
between the phrases.&lt;/p&gt;
&lt;p&gt;Back when audio processing was analog and real-time, the noise gate
had to be simple. It would notice when audio went either above or below
the threshold, and “open” or “close” the gate correspondingly. When the
gate is closed, the output is suppressed to remove the noise; when the
gate is open, the input goes to the output unchanged. To soften the
transition, the gate doesn’t open/close immediately but goes through the
&lt;em&gt;attack&lt;/em&gt; and &lt;em&gt;decay&lt;/em&gt; phases, spread across a short amount
of time, like 50ms.&lt;/p&gt;
&lt;p&gt;The de-facto standard noise gate plugin for audacity, &lt;a
href=&quot;https://wiki.audacityteam.org/wiki/Nyquist_Effect_Plug-ins#Noise_Gate&quot;&gt;noisegate.ny&lt;/a&gt;,
does a pretty good job emulating an analog noise gate but also doesn’t
do much beyond that. There are two major drawbacks of that plugin, which
I can summarize as:&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;Sometimes it doesn’t reduce enough&lt;/li&gt;
&lt;li&gt;Sometimes it reduces too much&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;So I implemented my own noise gate plugin that addresses these
issues—and it is also much faster. But before I get into that, let me
explain in more detail the ways in which the usual noise gate plugins
fall short.&lt;/p&gt;
&lt;h2 id=&quot;not-enough-reduction&quot;&gt;Not enough reduction&lt;/h2&gt;
&lt;p&gt;A typical noise gate (including noisegate.ny) closes when the
loudness (or, more precisely, the amplitude) of the signal falls below a
specified threshold. Once the amplitude exceeds the threshold, the gate
opens. Therefore, a single loud click, even a very short one, can open
the gate.&lt;/p&gt;
&lt;figure&gt;
&lt;img src=&quot;/img/better-noise-gate/fig1.png&quot;
alt=&quot;Higher-amplitude short clicks among the noise can open the noise gate and let the noise through.&quot; /&gt;
&lt;figcaption aria-hidden=&quot;true&quot;&gt;Higher-amplitude short clicks among the
noise can open the noise gate and let the noise through.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Therefore, a single run of the noise gate is often not enough to get
rid of all the noise. You would need then to go and manually remove the
remaining patches of noise and clicks, or to run a second (and sometimes
third) noise gate with different parameters.&lt;/p&gt;
&lt;figure&gt;
&lt;img src=&quot;/img/better-noise-gate/fig2.png&quot;
alt=&quot;Although most of the noise is gone, a few clicks remain and have to be removed manually or with a second noise gate.&quot; /&gt;
&lt;figcaption aria-hidden=&quot;true&quot;&gt;Although most of the noise is gone, a few
clicks remain and have to be removed manually or with a second noise
gate.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h2 id=&quot;too-much-reduction&quot;&gt;Too much reduction&lt;/h2&gt;
&lt;p&gt;So why not just raise the threshold to cover the peaks as well?
That’s the second issue with the usual noise gates. Near the beginning
or the end of a phrase, the sound is usually softer and may not be
enough to open the gate. This results in a characteristic loss of
syllables. For example, here’s a short clip from The Effort Report
podcast.&lt;/p&gt;
&lt;audio id=&quot;before-ng&quot; controls style=&quot;width: 100%;&quot; preload=&quot;metadata&quot;&gt;
&lt;source src=&quot;/files/2019-01-12-better-noise-gate/before-ng.mp3&quot; type=&quot;audio/mp3&quot;&gt;
&lt;/audio&gt;
&lt;p&gt;And here’s the same clip after applying a noise gate with
threshold=-47dB, level reduction=-50dB, and attack/decay=50ms.&lt;/p&gt;
&lt;audio id=&quot;after-ng&quot; controls style=&quot;width: 100%;&quot; preload=&quot;metadata&quot;&gt;
&lt;source src=&quot;/files/2019-01-12-better-noise-gate/after-ng.mp3&quot; type=&quot;audio/mp3&quot;&gt;
&lt;/audio&gt;
&lt;p&gt;In the original clip, the “f” sound in “off” can barely be heard, but
the brain still registers it. After the noise gate, it’s lost
completely, and the phrase sounds unnatural: &lt;em&gt;make sure you’ve got
your ringer turned o’&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;There are a few strategies to fight this annoying effect:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;lower the threshold, e.g. -55dB instead of -47dB.&lt;/li&gt;
&lt;li&gt;increase the attack/decay, e.g. 500ms instead of 50ms.&lt;/li&gt;
&lt;li&gt;lower the reduction level, e.g. -10dB instead of -50dB.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In the past, I used a combination of these tricks and several runs of
the noise gate to get rid of all the noise while trying not to damage
the speech. It worked but took a lot of time.&lt;/p&gt;
&lt;p&gt;To be fair, there are noise gates implementation that, in addition to
attack and decay, also have a &lt;em&gt;sustain&lt;/em&gt; phase—but noisegate.ny is
not one of them.&lt;/p&gt;
&lt;h2 id=&quot;a-better-noise-gate&quot;&gt;A better noise gate&lt;/h2&gt;
&lt;p&gt;In addition to the traditional Threshold and Attack/decay parameters,
my noise gate has two new parameters: window size and the minimum amount
of non-silent audio per window.&lt;/p&gt;
&lt;figure&gt;
&lt;img src=&quot;/img/better-noise-gate/my-noise-gate.png&quot;
alt=&quot;My noise gate’s settings window.&quot; /&gt;
&lt;figcaption aria-hidden=&quot;true&quot;&gt;My noise gate’s settings
window.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;At each time point, the noise gate makes the decision whether to
silence it or not. To make the decision, we consider a symmetric window
around the current time point, and whose width, in milliseconds, is
given by the user (the second parameters on the screenshot above). Then
we calculate the amount of non-silent audio, in milliseconds, present
within this window. The non-silent audio is defined as audio whose
amplitude exceeds the threshold (the first parameter on the screenshot).
If the amount of non-silent audio exceeds the critical duration (the
third parameter), then the current audio sample is not silenced.
Otherwise, i.e. if most audio in the vicinity of the current time point
falls below the threshold, the current sample is silenced.&lt;/p&gt;
&lt;p&gt;So why is this algorithm a better noise gate? First, consider the
case when the traditional noise gate doesn’t reduce enough. That happens
when there’s a high-amplitude spike in the audio. These spikes or clicks
tend to be very short, and if they are surrounded by low-volume noise,
then in their window there won’t be enough non-silence to open the
gate.&lt;/p&gt;
&lt;p&gt;Next, consider the case when the traditional noise gate reduces too
much. This typically happens near at the boundaries between silence and
non-silence. Therefore, even if the instanteneous volume is low, in the
window around it there will be enough high-volume signal to keep the
gate open.&lt;/p&gt;
&lt;h2 id=&quot;choosing-the-parameters&quot;&gt;Choosing the parameters&lt;/h2&gt;
&lt;p&gt;Here’s how I suggest to pick the right parameters for the noise
gate.&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;Set the threshold to the general noise floor level, ignoring the
occasional spikes and clicks.&lt;/li&gt;
&lt;li&gt;Find one of the widest (i.e. longest) spikes/clicks that rise above
the threshold. Measure the duration of the part that’s above the
threshold and set the “Non-silent audio per window” slightly above that
value. If there are several wide clicks next to each other, add their
widths together.&lt;/li&gt;
&lt;li&gt;Given the threshold you chose on step 1, think about how long the
beginning or ending of a phrase can be that falls below the threshold.
Let’s say it’s 600ms. To get the window size, add that duration to the
value of parameter #3 (non-silent audio per window) and double it. For
instance, let’s say you chose 150ms on step 2. Then your window size
will be 2×(600ms+150ms)=1500ms.&lt;/li&gt;
&lt;li&gt;The attack/decay choice is subjective. I usually pick 50ms. It
shouldn’t matter much because by the time the gate closes (assuming you
picked the good values for the other parameters), any speech should be
over, and we are only dealing with noise at this point. This is in
contrast to the standard noise gates, where attack/decay may cover
quieter parts of the speech.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Also, if you use a noise gate (any noise gate!), make sure to run
noise reduction first. When there’s a uniform noise behind the speech
that suddenly disappears in between the phrases, it sounds very
unprofessional.&lt;/p&gt;
&lt;h2 id=&quot;ladspa&quot;&gt;LADSPA&lt;/h2&gt;
&lt;p&gt;My noise gate uses the plugin interface called &lt;a
href=&quot;https://www.ladspa.org/&quot;&gt;LADSPA&lt;/a&gt;, which stands for Linux Audio
Developer’s Simple Plugin API. This is different from most Audacity
plugins, which use the Nyquist interface. The disadvantage of LADSPA is
that you’ll have to compile the plugin for your platform. But there are
quite a few advantages:&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;It is very fast. I ran both my noise gate and Steve’s noisegate.ny
on the same track, 1h19m41s in length. noigate.ny took 1 minute 18
seconds to finish; my noise gate took only 9 seconds.&lt;/li&gt;
&lt;li&gt;The progress bar in Audacity is accurate for LADSPA plugins. When I
ran noisegate.ny, the progress bar reached 100% and stayed there at 30
seconds—by which time the plugin wasn’t even halfway done.&lt;/li&gt;
&lt;li&gt;It processes the track incrementally, so it consumes much less
memory.&lt;/li&gt;
&lt;li&gt;In Audacity, there is a live preview for LADSPA plugins but not
Nyquist plugins.&lt;/li&gt;
&lt;li&gt;It can work under a variety of audio editors and DAWs that support
the LADSPA interface (Audacity, Ardour, GNU Sound etc.), unlike Nyquist,
which, to my knowledge, is only integrated into Audacity (although there
exists a standalone Nyquist interpreter). There is even a command-line
program distributed with LADSPA, &lt;code&gt;applyplugin&lt;/code&gt;, that can
apply a plugin to an audio file in batch mode, without any GUI.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Give it a try. The source and installation instructions are on
GitHub: &lt;a href=&quot;https://github.com/UnkindPartition/noise-gate&quot;
class=&quot;uri&quot;&gt;https://github.com/UnkindPartition/noise-gate&lt;/a&gt;.&lt;/p&gt;
</description>
                        <pubDate>Sat, 12 Jan 2019 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2019-01-12-better-noise-gate</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2019-01-12-better-noise-gate.html</guid>
                </item>
        
                <item>
                        <title>Homology, similarity, and alignment</title>
                        <description>&lt;p&gt;Although homology, similarity, and alignment are all relatively well
defined notions in biology and computer science, scientists sometimes
get confused about their meaning or the relationships between them. The
results range from annoyed colleagues to &lt;a
href=&quot;http://www.theallium.com/science-life/evolutionist-loses-it-as-colleague-conflates-homology-and-similarity-yet-again/&quot;&gt;very
annoyed colleagues&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;So let’s sort these things out.&lt;/p&gt;
&lt;h2 id=&quot;definitions&quot;&gt;Definitions&lt;/h2&gt;
&lt;p&gt;To keep things simple and concrete, I’ll be mostly talking about DNA
sequences, but everything here applies equally to RNA or amino acid
sequences.&lt;/p&gt;
&lt;h3 id=&quot;homology&quot;&gt;Homology&lt;/h3&gt;
&lt;p&gt;Homology is a concept from evolutionary biology. It means that two
DNA sequences have a common evolutionary origin (&lt;a
href=&quot;https://doi.org/10.1016/0092-8674(87)90322-9&quot;&gt;Reeck et al.,
1987&lt;/a&gt;). For example, the mouse gene Hba-a1 is homologous with the
human gene HBA1 because both species inherited it from their latest
common ancestor. Homologous sequences can be divided into paralogous and
orthologous sequences, although that distinction won’t be important
here.&lt;/p&gt;
&lt;h3 id=&quot;sequence-similarity&quot;&gt;Sequence similarity&lt;/h3&gt;
&lt;p&gt;Sequence similarity is a concept from computational biology and
computer science. Sequence similarity is a number that shows how much
two sequences are similar. Sequence similarity is sometimes, but &lt;a
href=&quot;https://en.wikipedia.org/wiki/Smith%E2%80%93Waterman_algorithm&quot;&gt;not
always&lt;/a&gt;, defined via &lt;em&gt;sequence distance&lt;/em&gt;: the smaller the
distance, the more similar the sequences&lt;a href=&quot;#fn1&quot;
class=&quot;footnote-ref&quot; id=&quot;fnref1&quot; role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;1&lt;/sup&gt;&lt;/a&gt;.
For instance, the following two DNA sequences are highly similar (the
differences are highlighted in red):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;GTC&lt;span style=&quot;color: red;&quot;&gt;C&lt;/span&gt;TCATAAC&lt;span style=&quot;color: red;&quot;&gt;T&lt;/span&gt;CTCTCTAG
GTC&lt;span style=&quot;color: red;&quot;&gt;G&lt;/span&gt;TCATAAC&lt;span style=&quot;color: red;&quot;&gt; &lt;/span&gt;CTCTCTAG&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Their similarity is witnessed by their low &lt;a
href=&quot;https://en.wikipedia.org/wiki/Levenshtein_distance&quot;&gt;Levenshtein
distance&lt;/a&gt; of 2—it only takes two edit operations (one substitution
and one deletion) to transform the first sequence into the second one&lt;a
href=&quot;#fn2&quot; class=&quot;footnote-ref&quot; id=&quot;fnref2&quot;
role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;2&lt;/sup&gt;&lt;/a&gt;. But there are other distance
metrics on sequences, and there are also similarity metrics not
expressible as distances. Therefore, while sequence similarity is always
a number determined based on two sequences, the specifics of how that
number is calculated may vary.&lt;/p&gt;
&lt;p&gt;Sometimes the similarity score is expressed as a percentage, namely
“percent similarity” or “percent identity”. Percent &lt;em&gt;identity&lt;/em&gt;
usually refers to the ratio of the number of matching residues to the
total length of the alignment (see below), e.g. 18/20=90% in the example
above. See also &lt;a
href=&quot;https://lh3.github.io/2018/11/25/on-the-definition-of-sequence-identity&quot;&gt;Li,
2018&lt;/a&gt;. Percent &lt;em&gt;similarity&lt;/em&gt; counts “similar” residues (usually
amino acids) in addition to the identical ones. The similarity between
amino acids can be defined either by their chemical properties or based
on a &lt;a href=&quot;https://en.wikipedia.org/wiki/Point_accepted_mutation&quot;&gt;PAM
matrix&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&quot;alignment&quot;&gt;Alignment&lt;/h3&gt;
&lt;p&gt;Alignment is another concept from computational biology. It is simply
any way to align two sequences one below another, possibly with gaps&lt;a
href=&quot;#fn3&quot; class=&quot;footnote-ref&quot; id=&quot;fnref3&quot;
role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;3&lt;/sup&gt;&lt;/a&gt; (&lt;a
href=&quot;https://doi.org/10.1017/CBO9780511574931&quot;&gt;Gusfield, 1997&lt;/a&gt;). I
already showed an example alignment above. Here it is again, this time
with the gaps (deletions) indicated by a hyphen (&lt;code&gt;-&lt;/code&gt;), as is
customary for sequence alignments:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;GTC&lt;span style=&quot;color: red;&quot;&gt;C&lt;/span&gt;TCATAAC&lt;span style=&quot;color: red;&quot;&gt;T&lt;/span&gt;CTCTCTAG
GTC&lt;span style=&quot;color: red;&quot;&gt;G&lt;/span&gt;TCATAAC&lt;span style=&quot;color: red;&quot;&gt;-&lt;/span&gt;CTCTCTAG&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You would think that this is &lt;em&gt;the&lt;/em&gt; alignment for these two
strings, but according to the definition, the following is also a valid
alignment:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;GTC&lt;span style=&quot;color: red;&quot;&gt;C&lt;/span&gt;TCAT&lt;span style=&quot;color: red;&quot;&gt;-&lt;/span&gt;A&lt;span style=&quot;color: red;&quot;&gt;A&lt;/span&gt;C&lt;span style=&quot;color: red;&quot;&gt;T&lt;/span&gt;CTCTCTAG
GTC&lt;span style=&quot;color: red;&quot;&gt;G&lt;/span&gt;TCAT&lt;span style=&quot;color: red;&quot;&gt;A&lt;/span&gt;A&lt;span style=&quot;color: red;&quot;&gt;-&lt;/span&gt;C&lt;span style=&quot;color: red;&quot;&gt;-&lt;/span&gt;CTCTCTAG&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And this one, too:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span style=&quot;color: red;&quot;&gt;GTCCTCATAACTCTCTCTAG-------------------&lt;/span&gt;
&lt;span style=&quot;color: red;&quot;&gt;--------------------GTCGTCATAACCTCTCTAG&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;An &lt;em&gt;alignment algorithm&lt;/em&gt; usually has a scoring function, which
assigns every alignment a numeric score indicating how good an alignment
it is, and tries to find the best alignment according to its scoring
function.&lt;/p&gt;
&lt;h2 id=&quot;relationships&quot;&gt;Relationships&lt;/h2&gt;
&lt;p&gt;To understand these terms better, it helps to see how they are
related to one another.&lt;/p&gt;
&lt;h3 id=&quot;homology-vs.-similarity&quot;&gt;Homology vs. similarity&lt;/h3&gt;
&lt;p&gt;Neither homology nor high similarity imply the other one. Two
sequences can be similar or even identical either by chance (if they are
short) or by design (if synthesized). And two homologous loci can
quickly diverge in their DNA sequence if they are not constrained by
natural selection.&lt;/p&gt;
&lt;p&gt;Whereas similarity is a property of the sequences (strings)
themselves and does not depend on where they came from, homology is the
opposite—a property of how two things (e.g. genes) came to be,
regardless of their nucleotide content.&lt;/p&gt;
&lt;p&gt;Thus, it does not even make sense to ask whether these two (similar!)
sequences are homologous without putting them in the context of the
genomes and organisms in which they evolved:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;GTC&lt;span style=&quot;color: red;&quot;&gt;C&lt;/span&gt;TCATAAC&lt;span style=&quot;color: red;&quot;&gt;T&lt;/span&gt;CTCTCTAG
GTC&lt;span style=&quot;color: red;&quot;&gt;G&lt;/span&gt;TCATAAC&lt;span style=&quot;color: red;&quot;&gt; &lt;/span&gt;CTCTCTAG&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In fact, I generated these sequences randomly using R, so I can
confidently say that they are not homologous—they simply aren’t objects
of evolution.&lt;/p&gt;
&lt;p&gt;That said, there are two valid connections between homology and
similarity, and they are the source of confusion between these
notions:&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;Similarity can be used to infer homology. Specifically, if the two
similar genomic sequences are long and complex enough to have unlikely
arisen independently even under similar selective pressures, then this
is a strong evidence for their homology.&lt;/li&gt;
&lt;li&gt;Most of the homologous loci &lt;em&gt;that we observe&lt;/em&gt; have high
similarity. I emphasized &lt;em&gt;“that we observe”&lt;/em&gt; because there is an
obvious circularity and bias here: we only know that two regions are
homologous when they are similar. If we could somehow sample homologous
regions in different organisms in an unbiased way, perhaps we would find
much less similarity than we are accustomed to.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;similarity-vs.-alignment&quot;&gt;Similarity vs. alignment&lt;/h3&gt;
&lt;p&gt;An alignment could be converted to a similarity score using a scoring
function. The simplest scoring function could be “add 1 for every
matching characters in the alignment, 0 for every mismatch or space
(gap)”. But there are many different scoring functions, and so there
isn’t one canonical similarity corresponding to an alignment.&lt;/p&gt;
&lt;p&gt;Usually when people talk about an alignment, they mean the optimal
(best) alignment relative to a particular scoring function, but we need
to remember that an alignment does not have to be optimal.&lt;/p&gt;
&lt;p&gt;Similarity &lt;em&gt;could&lt;/em&gt; be defined through an
alignment—specifically, as the score of the best (highest-scoring)
alignment between the two sequences.&lt;/p&gt;
&lt;p&gt;Similarity &lt;em&gt;could also&lt;/em&gt; be defined in many other
ways—e.g. through a locality-sensitive hash (&lt;a
href=&quot;https://doi.org/10.1186/s13059-016-0997-x&quot;&gt;Ondov et al.,
2016&lt;/a&gt;).&lt;/p&gt;
&lt;h3 id=&quot;alignment-vs.-homology&quot;&gt;Alignment vs. homology&lt;/h3&gt;
&lt;p&gt;If two regions are homologous, they could be aligned to underline
their evolutionary history. Let’s call an alignment in which aligned
positions have a common origin an &lt;em&gt;evolutionary alignment&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;The evolutionary alignment does not have to be the optimal alignment
with respect to any given scoring function. And vice versa, the optimal
alignment (such as one calculated by an alignment program) does not
necessarily reflect the evolutionary relationship between the
sequences.&lt;/p&gt;
&lt;p&gt;Let’s consider an example to illustrate this. In the ancestral
genome, there is a sequence &lt;code&gt;ATATATG&lt;/code&gt;. In one of the
lineages, the second and third bases got deleted, resulting in
&lt;code&gt;ATATG&lt;/code&gt;. The evolutionary pairwise alignment of the ancestor
and the lineage is&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
A&lt;span style=&quot;color: red;&quot;&gt;TA&lt;/span&gt;TATG
A&lt;span style=&quot;color: red;&quot;&gt;--&lt;/span&gt;TATG
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Note that, although this is an optimal alignment, it is not a
&lt;em&gt;unique&lt;/em&gt; optimal alignment. Assuming a simple scoring function
that assigns 0 to matches and −1 to mismatches, insertions, and
deletions, the alignments&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
AT&lt;span style=&quot;color: red;&quot;&gt;AT&lt;/span&gt;ATG
AT&lt;span style=&quot;color: red;&quot;&gt;--&lt;/span&gt;ATG
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;and&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
&lt;span style=&quot;color: red;&quot;&gt;AT&lt;/span&gt;ATATG
&lt;span style=&quot;color: red;&quot;&gt;--&lt;/span&gt;ATATG
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;have the same score of −2, even though they do not represent the
evolutionary relationship between the sequences.&lt;/p&gt;
&lt;p&gt;Also note that this alignment does not necessarily tell us about the
exact path by which we arrived from &lt;code&gt;ATATATG&lt;/code&gt; to
&lt;code&gt;ATATG&lt;/code&gt;. What if there were two mutational events: first,
&lt;code&gt;AT&lt;/code&gt; got duplicated into &lt;code&gt;ATAT&lt;/code&gt;, and then that
&lt;code&gt;ATAT&lt;/code&gt; got deleted? It would still result in the same
alignment.&lt;/p&gt;
&lt;p&gt;Now let’s consider another lineage, where the fifth base mutated to
G, resulting in &lt;code&gt;ATATGTG&lt;/code&gt;. The &lt;em&gt;optimal&lt;/em&gt; alignment
between the two lineages is&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
ATATG&lt;span style=&quot;color: red;&quot;&gt;--&lt;/span&gt;
ATATG&lt;span style=&quot;color: red;&quot;&gt;TG&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;with the score of −2. But this alignment does not reflect the
evolutionary history, because the two aligned &lt;code&gt;G&lt;/code&gt;s do not
have the same origin. Instead, the evolutionarily correct alignment
is&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
A&lt;span style=&quot;color: red;&quot;&gt;--&lt;/span&gt;T&lt;span style=&quot;color: red;&quot;&gt;A&lt;/span&gt;TG
A&lt;span style=&quot;color: red;&quot;&gt;TA&lt;/span&gt;T&lt;span style=&quot;color: red;&quot;&gt;G&lt;/span&gt;TG
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;having a suboptimal score of −3. This shows that the optimal
alignment and the evolutionary alignment do not have to coincide.&lt;/p&gt;
&lt;p&gt;To summarize, an alignment by itself does not imply any evolutionary
relationship between the sequences. The two aligned sequences do not
have to be homologous, and even if they are, the alignment does not
necessarily show which bases have a common origin, although an alignment
&lt;em&gt;can&lt;/em&gt; be used for this purpose. An alignment is just a way to
visualize the differences and similarities between two sequences; if
there is any extra meaning in a particular alignment, it has to be given
explicitly.&lt;/p&gt;
&lt;h2 id=&quot;acknowledgments&quot;&gt;Acknowledgments&lt;/h2&gt;
&lt;p&gt;Thanks to Nika Gurianova for the feedback on an earlier draft of this
article.&lt;/p&gt;
&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://doi.org/10.1016/0092-8674(87)90322-9&quot;&gt;Reeck, GR, de
Haën, C, Teller, DC, Doolittle, RF, Fitch, WM, Dickerson, RE, Chambon,
P, McLachlan, AD, Margoliash, E, Jukes, TH (1987). “Homology” in
proteins and nucleic acids: a terminology muddle and a way out of it.
Cell, 50, 5:667.&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://doi.org/10.1017/CBO9780511574931&quot;&gt;Gusfield, D.
(1997). Algorithms on Strings, Trees, and Sequences: Computer Science
and Computational Biology. Cambridge: Cambridge University
Press.&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://doi.org/10.1186/s13059-016-0997-x&quot;&gt;Ondov, BD,
Treangen, TJ, Melsted, P, Mallonee, AB, Bergman, NH, Koren, S,
Phillippy, AM (2016). Mash: fast genome and metagenome distance
estimation using MinHash. Genome Biol., 17, 1:132.&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a
href=&quot;https://lh3.github.io/2018/11/25/on-the-definition-of-sequence-identity&quot;&gt;Heng
Li. On the definition of sequence identity.&lt;/a&gt;&lt;/p&gt;
&lt;section id=&quot;footnotes&quot; class=&quot;footnotes footnotes-end-of-document&quot;
role=&quot;doc-endnotes&quot;&gt;
&lt;hr /&gt;
&lt;ol&gt;
&lt;li id=&quot;fn1&quot;&gt;&lt;p&gt;For something to be called a distance, it also needs to
satisfy the &lt;a
href=&quot;https://en.wikipedia.org/wiki/Metric_(mathematics)#Definition&quot;&gt;distance
axioms&lt;/a&gt;. That said, there are no agreed upon axioms for similarity
metrics, so a proper similarity metric could be derived from an improper
distance metric if desired.&lt;a href=&quot;#fnref1&quot; class=&quot;footnote-back&quot;
role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li id=&quot;fn2&quot;&gt;&lt;p&gt;Strictly speaking, the term “similarity” implies that
more similar sequences get &lt;em&gt;higher&lt;/em&gt; numbers, also known as
similarity scores. To transform a distance metric into a similarity
score we can simply negate it. So, if we wanted to be precise, we could
say that in our example the sequences have the distance of 2 and
similarity of −2.&lt;a href=&quot;#fnref2&quot; class=&quot;footnote-back&quot;
role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li id=&quot;fn3&quot;&gt;&lt;p&gt;This is more precisely called a &lt;em&gt;global pairwise
alignment&lt;/em&gt;, as opposed to a &lt;em&gt;multiple sequence alignment&lt;/em&gt; or
a &lt;em&gt;local alignment&lt;/em&gt;, which I won’t cover here.&lt;a href=&quot;#fnref3&quot;
class=&quot;footnote-back&quot; role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</description>
                        <pubDate>Sat, 05 Jan 2019 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2019-01-05-homology-similarity-alignment</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2019-01-05-homology-similarity-alignment.html</guid>
                </item>
        
                <item>
                        <title>Bioinformatics events in Europe in 2019</title>
                        <description>&lt;p&gt;Continuing the tradition from &lt;a
href=&quot;/articles/2017-12-27-europe-bioinformatics-events-2018&quot;&gt;last
year&lt;/a&gt;, here are some conferences and summer schools that will take
place in Europe in 2019 and may be of interest to fellow
bioinformaticians. I’ll be doing more curation this time, so the list
will be shorter but with higher signal to noise ratio.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;
Event
&lt;/th&gt;
&lt;th&gt;
Dates
&lt;/th&gt;
&lt;th&gt;
Location
&lt;/th&gt;
&lt;th&gt;
Early registration price
&lt;/th&gt;
&lt;th&gt;
Early registration deadline
&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;a
href=&quot;https://vibconferences.be/event/revolutionizing-next-generation-sequencing-3rd-edition&quot;&gt;Revolutionizing
Next-Generation Sequencing&lt;/a&gt;
&lt;/td&gt;
&lt;td&gt;
March 25–26
&lt;/td&gt;
&lt;td&gt;
Antwerp, Belgium
&lt;/td&gt;
&lt;td&gt;
€500
&lt;/td&gt;
&lt;td&gt;
February 11
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;a
href=&quot;http://meetings.embo.org/event/19-population-genomics&quot;&gt;Population
genomics: Background, tools and programming&lt;/a&gt;
&lt;/td&gt;
&lt;td&gt;
March 30–April 6
&lt;/td&gt;
&lt;td&gt;
Procida, Italy
&lt;/td&gt;
&lt;td&gt;
€1000
&lt;/td&gt;
&lt;td&gt;
January 31
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;a href=&quot;https://project.inria.fr/compsysbio2019/&quot;&gt;Advanced Lecture
Course on Computational Systems Biology&lt;/a&gt;
&lt;/td&gt;
&lt;td&gt;
March 31–April 6
&lt;/td&gt;
&lt;td&gt;
Aussois, France
&lt;/td&gt;
&lt;td&gt;
€800
&lt;/td&gt;
&lt;td&gt;
February 28
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;a href=&quot;https://www.mdc-berlin.de/epigencell&quot;&gt;Joint Summer School
“Epigenetics in Single Cells”&lt;/a&gt;
&lt;/td&gt;
&lt;td&gt;
April 3–10
&lt;/td&gt;
&lt;td&gt;
London, UK; Berlin, Germany
&lt;/td&gt;
&lt;td&gt;
Free
&lt;/td&gt;
&lt;td&gt;
February 15
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;a href=&quot;http://meetings.embo.org/event/19-whole-cell-modelling&quot;&gt;The
2019 whole-cell modeling summer school&lt;/a&gt;
&lt;/td&gt;
&lt;td&gt;
April 7–13
&lt;/td&gt;
&lt;td&gt;
Barcelona, Spain
&lt;/td&gt;
&lt;td&gt;
€1000
&lt;/td&gt;
&lt;td&gt;
December 1, 2018
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;a href=&quot;https://2019.eshg.org/&quot;&gt;European Human Genetics Conference
(ESHG)&lt;/a&gt;
&lt;/td&gt;
&lt;td&gt;
June 15–18
&lt;/td&gt;
&lt;td&gt;
Gothenburg, Sweden
&lt;/td&gt;
&lt;td&gt;
€500
&lt;/td&gt;
&lt;td&gt;
April 4
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;a href=&quot;https://www.iscb.org/ismbeccb2019&quot;&gt;European Conference on
Computational Biology&lt;/a&gt;
&lt;/td&gt;
&lt;td&gt;
July 21–25
&lt;/td&gt;
&lt;td&gt;
Basel, Switzerland
&lt;/td&gt;
&lt;td&gt;
CHF 942.38
&lt;/td&gt;
&lt;td&gt;
June 20
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;a
href=&quot;http://gtpb.igc.gulbenkian.pt/bicourses/2019/CPANG19/index.html&quot;&gt;CPANG:
Computational PANGenomics&lt;/a&gt;
&lt;/td&gt;
&lt;td&gt;
September 9–13
&lt;/td&gt;
&lt;td&gt;
Oeiras, Portugal
&lt;/td&gt;
&lt;td&gt;
€450
&lt;/td&gt;
&lt;td&gt;
September 2
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;a
href=&quot;https://www.basellife.org/2019/basel-life-structure/bc2/general.html&quot;&gt;[BC]²:
Basel Computational Biology Conference&lt;/a&gt;
&lt;/td&gt;
&lt;td&gt;
September 10–11
&lt;/td&gt;
&lt;td&gt;
Basel, Switzerland
&lt;/td&gt;
&lt;td&gt;
CHF 300
&lt;/td&gt;
&lt;td&gt;
June 12
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;a href=&quot;https://ngschool.eu/2019&quot;&gt;NGSchool&lt;/a&gt;
&lt;/td&gt;
&lt;td&gt;
October 24–31
&lt;/td&gt;
&lt;td&gt;
Białobrzegi, Poland
&lt;/td&gt;
&lt;td&gt;
&lt;/td&gt;
&lt;td&gt;
May 1
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;a href=&quot;https://eurobioc2019.bioconductor.org/&quot;&gt;European Bioconductor
Meeting&lt;/a&gt;
&lt;/td&gt;
&lt;td&gt;
December 9–10
&lt;/td&gt;
&lt;td&gt;
Brussels, Belgium
&lt;/td&gt;
&lt;td&gt;
€125
&lt;/td&gt;
&lt;td&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
</description>
                        <pubDate>Thu, 06 Dec 2018 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2018-12-06-europe-bioinformatics-events-2019</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2018-12-06-europe-bioinformatics-events-2019.html</guid>
                </item>
        
                <item>
                        <title>Tasty 1.2 supports dependencies between tests</title>
                        <description>&lt;p&gt;Tasty (&lt;a href=&quot;https://github.com/UnkindPartition/tasty&quot;&gt;GitHub&lt;/a&gt;,
&lt;a href=&quot;https://hackage.haskell.org/package/tasty&quot;&gt;Hackage&lt;/a&gt;) is a
versatile and extensible testing framework for Haskell. Using tasty, you
can quickly create a test suite consisting of unit tests, property tests
and &lt;a href=&quot;/articles/2017-12-04-golden-tests&quot;&gt;golden tests&lt;/a&gt;. Users
of tasty benefit from automatic parallelism, a rich filtering language
to choose which tests to run, sharing resources between tests and
more.&lt;/p&gt;
&lt;p&gt;Tasty 1.2 adds another &lt;a
href=&quot;https://github.com/UnkindPartition/tasty/issues/48&quot;&gt;long-awaited&lt;/a&gt;
feature: dependencies between tests. If the tests only ran sequentially,
dependencies wouldn’t be an issue: you could always arrange your tests
in the desired order.&lt;/p&gt;
&lt;p&gt;However, tasty runs all tests in parallel by default (using a
user-specified or automatically determined number of worker threads).
While it’s always been possible to force sequential execution by setting
the number of threads to 1, sometimes you want to take advantage of the
parallelism while also making sure that some tests run after some other
tests due to the tests’ side effects.&lt;/p&gt;
&lt;p&gt;This is now possible using the &lt;code&gt;after&lt;/code&gt; combinator:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb1&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb1-1&quot;&gt;&lt;a href=&quot;#cb1-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;testGroup &lt;span class=&quot;st&quot;&gt;&amp;quot;Tests accessing the same resource&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-2&quot;&gt;&lt;a href=&quot;#cb1-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  [ testCase &lt;span class=&quot;st&quot;&gt;&amp;quot;Test A&amp;quot;&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;...&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-3&quot;&gt;&lt;a href=&quot;#cb1-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  , after &lt;span class=&quot;dt&quot;&gt;AllFinish&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;quot;Test A&amp;quot;&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-4&quot;&gt;&lt;a href=&quot;#cb1-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      testCase &lt;span class=&quot;st&quot;&gt;&amp;quot;Test B&amp;quot;&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;...&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-5&quot;&gt;&lt;a href=&quot;#cb1-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  ]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;In this example, Test B will only start running after Test A has
finished—successfully or not. Alternatively, you can tell Test B to run
only when Test A succeeds (notice &lt;code&gt;AllSucceed&lt;/code&gt; instead of
&lt;code&gt;AllFinish&lt;/code&gt;):&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb2&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb2-1&quot;&gt;&lt;a href=&quot;#cb2-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;testGroup &lt;span class=&quot;st&quot;&gt;&amp;quot;Tests creating and using a resource&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-2&quot;&gt;&lt;a href=&quot;#cb2-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  [ testCase &lt;span class=&quot;st&quot;&gt;&amp;quot;Test A&amp;quot;&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;...&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-3&quot;&gt;&lt;a href=&quot;#cb2-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  , after &lt;span class=&quot;dt&quot;&gt;AllSucceed&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;quot;Test A&amp;quot;&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-4&quot;&gt;&lt;a href=&quot;#cb2-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      testCase &lt;span class=&quot;st&quot;&gt;&amp;quot;Test B&amp;quot;&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;...&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-5&quot;&gt;&lt;a href=&quot;#cb2-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  ]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The &lt;code&gt;&quot;Test A&quot;&lt;/code&gt; argument of &lt;code&gt;after&lt;/code&gt; in these
examples is not simply a test name—it is a pattern in tasty’s AWK-like
pattern language, so a test can depend simultaneously on a combination
of different tests from different subtrees.&lt;/p&gt;
&lt;p&gt;To learn more about dependencies in tasty, please refer to the &lt;a
href=&quot;https://github.com/UnkindPartition/tasty/blob/master/README.md#dependencies&quot;&gt;README&lt;/a&gt;
and the &lt;a
href=&quot;https://hackage.haskell.org/package/tasty-1.2/docs/Test-Tasty.html#g:6&quot;&gt;haddock
documentation&lt;/a&gt;.&lt;/p&gt;
</description>
                        <pubDate>Sat, 01 Dec 2018 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2018-12-01-tasty-dependencies</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2018-12-01-tasty-dependencies.html</guid>
                </item>
        
                <item>
                        <title>How do I record a podcast remotely? SquadCast vs. Zencastr vs. Cast vs. other options</title>
                        <description>&lt;p&gt;One of the most frequent questions beginner (and many experienced)
podcasters have is “how do I record a podcast with my co-hosts/guests
being far away?”&lt;/p&gt;
&lt;p&gt;If you want a simple recommendation, then use &lt;a
href=&quot;https://squadcast.fm/&quot;&gt;SquadCast&lt;/a&gt;. This is my own service of
choice since July 2020, and so far I’ve been pretty happy with it.&lt;/p&gt;
&lt;p&gt;If you want to explore other options, first let me explain which
factors to look at when choosing a service. Then I’ll share my own
experience of using different services.&lt;/p&gt;
&lt;h2 id=&quot;what-you-should-pay-attention-to&quot;&gt;What you should pay attention
to&lt;/h2&gt;
&lt;h3 id=&quot;are-you-getting-individual-tracks-or-a-mix&quot;&gt;Are you getting
individual tracks or a mix?&lt;/h3&gt;
&lt;p&gt;Once you finish recording, will you get a single file with all voices
in it, or a file (“track”) per participant containing only that
participant’s voice?&lt;/p&gt;
&lt;p&gt;You should always prefer recording individual tracks. It may seem
like more work to edit and post-process multiple tracks than a single
one, but if you care at all about your audio quality, getting that
quality out of a mixed track is very hard. Here are some things that a
multi-track recording process lets you do:&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;Apply a noise gate to each track, so that when someone is not
talking, their noise does not get into the final mix.&lt;/li&gt;
&lt;li&gt;If two participants talk at the same time, you can mute one of them
to let the other one be heard, or even let both of them be heard by
rearranging their utterances in time so that they don’t overlap.&lt;/li&gt;
&lt;li&gt;Adjust the audio levels of each participant so that their loudness
is roughly the same in the final mix.&lt;/li&gt;
&lt;li&gt;Use different effect settings (EQ, compression, de-noise, de-reverb)
for different participants.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;I find multi-track recording such an important feature for podcasters
that I won’t even consider here any options that don’t provide it.&lt;/p&gt;
&lt;h3 id=&quot;are-tracks-recorded-locally-or-remotely&quot;&gt;Are tracks recorded
locally or remotely?&lt;/h3&gt;
&lt;p&gt;Most remote recording services that do multi-track recording do them
&lt;em&gt;locally&lt;/em&gt;: each participant’s track is recorded on that
participant’s device, and then gets uploaded to the server once the
recording is finished (or progressively while it lasts). A notable
exception is &lt;a href=&quot;https://cleanfeed.net/&quot;&gt;Cleanfeed&lt;/a&gt;, which
records tracks on their servers in real-time.&lt;/p&gt;
&lt;p&gt;The advantages of recording locally (also known as “a double-ender”)
are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Since there is no need to compress audio for real-time transmission
over the network, it is generally recorded in higher quality locally
than remotely. However, this depends on the codecs used and the
available bandwidth.&lt;/li&gt;
&lt;li&gt;Locally recorded tracks are immune to network glitches. If your
guest’s voice turned robotic or simply vanished, their own computer
probably captured their voice in its original form.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;But there are also disadvantages:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The tracks recorded on different computers tend to get out of sync
with time — the effect known as “audio drift”. Some services attempt to
combat this with various degrees of success. However, in practice I tend
to readjust pieces of audio anyway to achieve the right duration of
pauses between speakers, so unless the drift is enormous, it doesn’t
really matter.&lt;/li&gt;
&lt;li&gt;When the audio resides on your guest’s computer, there’s somewhat
higher risk of it being lost or corrupted. When evaluating a service,
find out whether they provide any options to restore the audio if
something goes wrong, but also always have a backup recording on your
side.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;To elaborate on the last point: regardless of what service you use,
always record two tracks locally: one with the audio from your own
microphone, and another with the audio that goes into your headphones.
(For Linux, see my &lt;a
href=&quot;/articles/2017-07-21-record-audio-linux&quot;&gt;audio recording
guide&lt;/a&gt;; for other OSes, you can often use your DAW or a third-party
app to do that.)&lt;/p&gt;
&lt;p&gt;The first of these two tracks — the one with your own audio —
probably will be of higher quality than the same track recorded by the
service (even when the service records locally), so if the audio drift
is not too bad, you can routinely use it in the podcast. On the other
hand, the second track — the one with your guests — will probably have
lower quality than the one recorded by the service (and will be a
mix-down when you have multipe guests), so you wouldn’t normally use it
— but if something goes wrong with the service, you’ll be glad you have
it.&lt;/p&gt;
&lt;p&gt;To summarize, I generally prefer services that record locally, but in
some cases Cleanfeed can be a good alternative.&lt;/p&gt;
&lt;h3 id=&quot;is-there-video&quot;&gt;Is there video?&lt;/h3&gt;
&lt;p&gt;Here I am not talking about recording video — I am talking about
being able to see other participants while recording an audio-only
podcast with them.&lt;/p&gt;
&lt;p&gt;While video is not required for recording podcasts, it’s very nice to
have. In addition to being generally helpful for establishing rapport,
here are some specific situations in which I’ve found it useful:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;When there are issues with guest’s audio (like bad mic positioning),
they are much easier to diagnose and address when I can see what’s going
on on their side.&lt;/li&gt;
&lt;li&gt;When the guest speaks, I can acknowledge their words with simple
nods, instead of polluting the audio with regular &lt;em&gt;uh-huh&lt;/em&gt;’s.
When they or I need a bit of time to think on what to say, we don’t need
to use filler sounds to let other person know we haven’t dropped
off.&lt;/li&gt;
&lt;li&gt;My co-host and I can use small gestures to coordinate who’s asking
the next question.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;can-the-guest-record-on-a-mobile-device&quot;&gt;Can the guest record on
a mobile device?&lt;/h3&gt;
&lt;p&gt;When the guest doesn’t have an external microphone or a headset, a
smartphone’s microphone can potentially give much better results than a
laptop’s built-in microphone, though I haven’t tried this in practice
yet.&lt;/p&gt;
&lt;h2 id=&quot;specific-services&quot;&gt;Specific services&lt;/h2&gt;
&lt;p&gt;Here’s a list of remote-recording services you can try:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.squadcast.fm/&quot;&gt;SquadCast&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://riverside.fm/&quot;&gt;Riverside&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://remotely.fm/&quot;&gt;Remotely&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.getwelder.com/&quot;&gt;Welder&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://ecastr.com/&quot;&gt;Ennuicastr&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://tryca.st/&quot;&gt;Cast&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://zencastr.com/&quot;&gt;Zencastr&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://cleanfeed.net/&quot;&gt;Cleanfeed&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Out of these:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Cleanfeed records audio on their servers; all the other ones record
locally. Welder offers simultaneous local and server-side recording (the
latter considered a backup).&lt;/li&gt;
&lt;li&gt;SquadCast, Zencastr, Riverside, Remotely, and Welder have video
during recording.&lt;/li&gt;
&lt;li&gt;I’ve only used Zencastr, Cast, and SquadCast for a significant
amount of time. I left Zencastr and Cast because of audio issues —
subtle ones in the case of Cast, and no so subtle ones in the case of
Zencastr. I’m happy with the quality of SquadCast recordings so
far.&lt;/li&gt;
&lt;li&gt;Also, with both Cast and Zencastr I had (very rare) cases when the
service would not work for a guest. I am yet to encounter such problem
with SquadCast.&lt;/li&gt;
&lt;li&gt;Ennuicastr is the only one that is open source. It is currently in
beta and lacks video, but other than that it looks very promising.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The only service I would definitely advise against is &lt;a
href=&quot;https://www.ringr.com/&quot;&gt;RINGR&lt;/a&gt;:&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;This was the only service I couldn’t make work at all.&lt;/li&gt;
&lt;li&gt;Despite advertising a free trial, they charged me and never
refunded, even after my explicit request.&lt;/li&gt;
&lt;li&gt;Their Android app requires a lot of permissions, including your
identity, contacts, files, Wi-Fi connection information, and device ID
and call information.&lt;/li&gt;
&lt;/ol&gt;
</description>
                        <pubDate>Sun, 28 Oct 2018 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2018-10-28-remote-recording</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2018-10-28-remote-recording.html</guid>
                </item>
        
                <item>
                        <title>How to pass a logical matrix to RStan</title>
                        <description>&lt;!-- I knitted the Rmd document in _sources but then hand-edited the result,
     so don&apos;t re-generate it.
--&gt;
&lt;p&gt;I ran into this problem with RStan today, and I’m sure I’ve had it at
least once in the past, and it took me a ridiculously long time to
figure out, so I’m documenting it here.&lt;/p&gt;
&lt;p&gt;Suppose you need to pass a multidimensional logical array to RStan
(&lt;code&gt;events&lt;/code&gt; in the example below). The details of the model
don’t matter; let’s say it’s a simple beta-binomial model:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb1&quot;&gt;&lt;pre class=&quot;sourceCode r&quot;&gt;&lt;code class=&quot;sourceCode r&quot;&gt;&lt;span id=&quot;cb1-1&quot;&gt;&lt;a href=&quot;#cb1-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;model &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;stan_model&lt;/span&gt;(&lt;span class=&quot;at&quot;&gt;auto_write =&lt;/span&gt; T, &lt;span class=&quot;at&quot;&gt;model_code =&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-2&quot;&gt;&lt;a href=&quot;#cb1-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;st&quot;&gt;data {&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-3&quot;&gt;&lt;a href=&quot;#cb1-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;st&quot;&gt;  int&amp;lt;lower=1&amp;gt; m;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-4&quot;&gt;&lt;a href=&quot;#cb1-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;st&quot;&gt;  int&amp;lt;lower=1&amp;gt; n;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-5&quot;&gt;&lt;a href=&quot;#cb1-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;st&quot;&gt;  int&amp;lt;lower=0,upper=1&amp;gt; events[m,n];&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-6&quot;&gt;&lt;a href=&quot;#cb1-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;st&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-7&quot;&gt;&lt;a href=&quot;#cb1-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;st&quot;&gt;parameters {&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-8&quot;&gt;&lt;a href=&quot;#cb1-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;st&quot;&gt;  real&amp;lt;lower=0&amp;gt; a;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-9&quot;&gt;&lt;a href=&quot;#cb1-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;st&quot;&gt;  real&amp;lt;lower=0&amp;gt; b;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-10&quot;&gt;&lt;a href=&quot;#cb1-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;st&quot;&gt;  vector&amp;lt;lower=0,upper=1&amp;gt;[m] theta;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-11&quot;&gt;&lt;a href=&quot;#cb1-11&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;st&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-12&quot;&gt;&lt;a href=&quot;#cb1-12&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;st&quot;&gt;model {&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-13&quot;&gt;&lt;a href=&quot;#cb1-13&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;st&quot;&gt;  theta ~ beta(a,b);&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-14&quot;&gt;&lt;a href=&quot;#cb1-14&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;st&quot;&gt;  for (i in 1:m) {&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-15&quot;&gt;&lt;a href=&quot;#cb1-15&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;st&quot;&gt;    sum(events[i]) ~ binomial(n, theta[i]);&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-16&quot;&gt;&lt;a href=&quot;#cb1-16&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;st&quot;&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-17&quot;&gt;&lt;a href=&quot;#cb1-17&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;st&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-18&quot;&gt;&lt;a href=&quot;#cb1-18&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;st&quot;&gt;&amp;quot;&lt;/span&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The corresponding R code might look like this:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb2&quot;&gt;&lt;pre class=&quot;sourceCode r&quot;&gt;&lt;code class=&quot;sourceCode r&quot;&gt;&lt;span id=&quot;cb2-1&quot;&gt;&lt;a href=&quot;#cb2-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;fu&quot;&gt;library&lt;/span&gt;(rstan)&lt;/span&gt;
&lt;span id=&quot;cb2-2&quot;&gt;&lt;a href=&quot;#cb2-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-3&quot;&gt;&lt;a href=&quot;#cb2-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;model &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;stan_model&lt;/span&gt;(&lt;span class=&quot;st&quot;&gt;&amp;quot;model.stan&amp;quot;&lt;/span&gt;, &lt;span class=&quot;at&quot;&gt;auto_write =&lt;/span&gt; T)&lt;/span&gt;
&lt;span id=&quot;cb2-4&quot;&gt;&lt;a href=&quot;#cb2-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;a &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;3&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-5&quot;&gt;&lt;a href=&quot;#cb2-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;b &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;5&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-6&quot;&gt;&lt;a href=&quot;#cb2-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;n &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;20&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-7&quot;&gt;&lt;a href=&quot;#cb2-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;m &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;30&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-8&quot;&gt;&lt;a href=&quot;#cb2-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;events &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;t&lt;/span&gt;(&lt;span class=&quot;fu&quot;&gt;sapply&lt;/span&gt;(&lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;sc&quot;&gt;:&lt;/span&gt;m,&lt;/span&gt;
&lt;span id=&quot;cb2-9&quot;&gt;&lt;a href=&quot;#cb2-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;cf&quot;&gt;function&lt;/span&gt;(i) {&lt;/span&gt;
&lt;span id=&quot;cb2-10&quot;&gt;&lt;a href=&quot;#cb2-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    p &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;rbeta&lt;/span&gt;(&lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;, a, b)&lt;/span&gt;
&lt;span id=&quot;cb2-11&quot;&gt;&lt;a href=&quot;#cb2-11&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;fu&quot;&gt;as.logical&lt;/span&gt;(&lt;span class=&quot;fu&quot;&gt;rbinom&lt;/span&gt;(n, &lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;, p))&lt;/span&gt;
&lt;span id=&quot;cb2-12&quot;&gt;&lt;a href=&quot;#cb2-12&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  }))&lt;/span&gt;
&lt;span id=&quot;cb2-13&quot;&gt;&lt;a href=&quot;#cb2-13&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-14&quot;&gt;&lt;a href=&quot;#cb2-14&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;fu&quot;&gt;sampling&lt;/span&gt;(model, &lt;span class=&quot;at&quot;&gt;data =&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;list&lt;/span&gt;(&lt;span class=&quot;at&quot;&gt;m =&lt;/span&gt; m, &lt;span class=&quot;at&quot;&gt;n =&lt;/span&gt; n, &lt;span class=&quot;at&quot;&gt;events =&lt;/span&gt; events))&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;But this results in the following error:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Error in new_CppObject_xp(fields$.module, fields$.pointer, ...) : 
  Exception: mismatch in number dimensions declared and found in context; processing stage=data initialization; variable name=events; dims declared=(30,20); dims found=(600)  (in &amp;#39;model3e955026c5b4_model&amp;#39; at line 4)
## failed to create the sampler; sampling not done&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The important bits are
&lt;code&gt;declared=(30,20); dims found=(600)&lt;/code&gt;. It looks like the
&lt;code&gt;events&lt;/code&gt; matrix got flattened… but why? We can double check
that &lt;code&gt;events&lt;/code&gt; is still a matrix of the correct
dimensions:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb4&quot;&gt;&lt;pre class=&quot;sourceCode r&quot;&gt;&lt;code class=&quot;sourceCode r&quot;&gt;&lt;span id=&quot;cb4-1&quot;&gt;&lt;a href=&quot;#cb4-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;fu&quot;&gt;class&lt;/span&gt;(events)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;pre&gt;&lt;code&gt;## [1] &amp;quot;matrix&amp;quot;&lt;/code&gt;&lt;/pre&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb6&quot;&gt;&lt;pre class=&quot;sourceCode r&quot;&gt;&lt;code class=&quot;sourceCode r&quot;&gt;&lt;span id=&quot;cb6-1&quot;&gt;&lt;a href=&quot;#cb6-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;fu&quot;&gt;dim&lt;/span&gt;(events)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;pre&gt;&lt;code&gt;## [1] 30 20&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here’s what’s going on. Because &lt;code&gt;events&lt;/code&gt; in R is a
&lt;em&gt;logical&lt;/em&gt; (i.e. boolean) matrix, and &lt;code&gt;events&lt;/code&gt; in Stan
is an &lt;em&gt;integer&lt;/em&gt; two-dimensional array, RStan tries to convert the
former to the latter by calling &lt;code&gt;as.integer&lt;/code&gt;. And indeed, we
can check that &lt;code&gt;as.integer&lt;/code&gt; flattens the matrix.&lt;/p&gt;
&lt;p&gt;So how do you convert a logical matrix to an integer one? There is
certainly more than one way to do it, but a quick and dirty solution,
which I found in the archives of &lt;a
href=&quot;https://stat.ethz.ch/pipermail/r-help/2011-January/265121.html&quot;&gt;r-help&lt;/a&gt;,
is to add a 0 to it. So:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb8&quot;&gt;&lt;pre class=&quot;sourceCode r&quot;&gt;&lt;code class=&quot;sourceCode r&quot;&gt;&lt;span id=&quot;cb8-1&quot;&gt;&lt;a href=&quot;#cb8-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;fu&quot;&gt;sampling&lt;/span&gt;(model, &lt;span class=&quot;at&quot;&gt;data =&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;list&lt;/span&gt;(&lt;span class=&quot;at&quot;&gt;m =&lt;/span&gt; m, &lt;span class=&quot;at&quot;&gt;n =&lt;/span&gt; n, &lt;span class=&quot;at&quot;&gt;events =&lt;/span&gt; events &lt;span class=&quot;sc&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;0&lt;/span&gt;))&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
</description>
                        <pubDate>Fri, 24 Aug 2018 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2018-08-24-logical-matrix-stan</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2018-08-24-logical-matrix-stan.html</guid>
                </item>
        
                <item>
                        <title>Estimating the fraction of recurring events</title>
                        <description>&lt;!--

NOTE: edit the Rmd file in _source/estimate-recurring-events.Rmd, then
regenerate using

library(knitr)
knit(input=&quot;_source/estimate-recurring-events.Rmd&quot;, output=&quot;_posts/2018-08-22-estimate-recurring-events.md&quot;)
--&gt;
&lt;p&gt;Sometimes you have a collection of events and the number of times
each of them occurred. Each event is either unique, i.e. occurring only
once, or recurring. You don’t know which events are unique or recurring,
but you want to estimate the fraction of recurring events.&lt;/p&gt;
&lt;p&gt;I’ll give two examples, one from everyday life and one from
bioinformatics.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Everyday life example.&lt;/strong&gt; Let’s say you’re a small
business (a barbershop, a community theater, an electrical contractor
etc.) People have to call you in order to reserve seats or make
appointments, so you know the names of all your past customers and how
many times they ordered. Naturally, some clients enjoyed the experience
and will become your recurring customers, while others didn’t like it
and will never return. You’d like to know how many recurring customers
you have.&lt;/p&gt;
&lt;p&gt;Why not do the obvious thing and calculate the fraction of people who
ordered twice or more? Because some fraction of the customers who have
not reordered are also recurring customers—they just haven’t had a
chance or need to reorder yet. Of course, based on our data, we cannot
possibly tell &lt;em&gt;which&lt;/em&gt; of those customers will reorder; but we can
nevertheless estimate their fraction.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Bioinformatics example.&lt;/strong&gt; (Feel free to skip this
paragraph if you’re not into bioinformatics!) You are looking at
ChIP-seq peaks in &lt;span class=&quot;math inline&quot;&gt;\(n\)&lt;/span&gt; replicates. For
each peak, you can calculate how many replicates the peak was found in.
You want to estimate the number of replicable peaks. Again, while you
could just count the peaks that were found in 2 or more replicates, some
of the replicable peaks are expected to have only occurred once, and it
would be a shame to miss them.&lt;/p&gt;
&lt;p&gt;The key to this problem is the following observation. The set of
unique events (customers who ordered once or peaks present in only one
replicate) is “contaminated”: it consists of a mixture of recurring and
non-recurring events. But the set of events that occured two or more
times must only consist of recurring events. We can use these definitely
recurring events to estimate the rate with which events recur, and from
there find the expected number of recurring events that only occurred
once.&lt;/p&gt;
&lt;p&gt;To be more specific, let’s denote the total number of
&lt;em&gt;recurring&lt;/em&gt; events as &lt;span class=&quot;math inline&quot;&gt;\(m\)&lt;/span&gt;, and
the number of recurring events that occurred &lt;span
class=&quot;math inline&quot;&gt;\(k\)&lt;/span&gt; times as &lt;span
class=&quot;math inline&quot;&gt;\(m_k\)&lt;/span&gt; &lt;span
class=&quot;math inline&quot;&gt;\((k=1,2,\ldots)\)&lt;/span&gt;. Then we don’t know &lt;span
class=&quot;math inline&quot;&gt;\(m_1\)&lt;/span&gt; (because we don’t know how many truly
unique events there are), but we do know &lt;span
class=&quot;math inline&quot;&gt;\(m_2, m_3, \ldots\)&lt;/span&gt; What we would like to
estimate is &lt;span class=&quot;math inline&quot;&gt;\(m = m_1 + m_2 + \ldots\)&lt;/span&gt;
(Notice that I didn’t include &lt;span class=&quot;math inline&quot;&gt;\(m_0\)&lt;/span&gt;
here; see below on why.)&lt;/p&gt;
&lt;p&gt;The natural models for &lt;span class=&quot;math inline&quot;&gt;\(m_k\)&lt;/span&gt; are
the binomial and Poisson distributions. In the ChIP-seq example, where
there is a clear upper bound on &lt;span
class=&quot;math inline&quot;&gt;\(m_k\)&lt;/span&gt;—the number of replicates, &lt;span
class=&quot;math inline&quot;&gt;\(n\)&lt;/span&gt;—the binomial model is more appropriate.
The binomial model could also be applied in the case of a community
theater that has only given a small number of performances to date. In
other cases, when the upper bound is absent or large, the Poisson model
is a better choice. There are other models one could apply here
(including a negative binomial model or even nonparametric models), but
I won’t cover them here; see Bunge et al. (2014) for inspiration.&lt;/p&gt;
&lt;p&gt;Regardless of the model, we expect &lt;span
class=&quot;math inline&quot;&gt;\(m_k\)&lt;/span&gt; for high &lt;span
class=&quot;math inline&quot;&gt;\(k\)&lt;/span&gt; to be less informative because their
chances of being non-zero become very low. So it is natural to use &lt;span
class=&quot;math inline&quot;&gt;\(m_2\)&lt;/span&gt; and &lt;span
class=&quot;math inline&quot;&gt;\(m_3\)&lt;/span&gt; for estimation. (Because the negative
binomial distribution has an extra parameter, one would also need an
extra data point, &lt;span class=&quot;math inline&quot;&gt;\(m_4\)&lt;/span&gt;. This is why
the negative binomial model should only be used when the total number of
observations, &lt;span class=&quot;math inline&quot;&gt;\(\sum k\cdot m_k\)&lt;/span&gt;, is
large.)&lt;/p&gt;
&lt;h2 id=&quot;the-binomial-model&quot;&gt;The binomial model&lt;/h2&gt;
&lt;p&gt;In the binomial model with parameters &lt;span
class=&quot;math inline&quot;&gt;\(n\)&lt;/span&gt; and &lt;span
class=&quot;math inline&quot;&gt;\(\theta\)&lt;/span&gt;, the probabilities of &lt;span
class=&quot;math inline&quot;&gt;\(k=2\)&lt;/span&gt; and &lt;span
class=&quot;math inline&quot;&gt;\(k=3\)&lt;/span&gt; repetitions for a particular event
are:&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;math display&quot;&gt;\[\begin{align*}
p\{k=2\} = {n\choose 2} \theta^2(1-\theta)^{n-2}; \\
p\{k=3\} = {n\choose 3} \theta^3(1-\theta)^{n-3}.
\end{align*}\]&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Dividing the second equation by the first gives&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;math display&quot;&gt;\[
\frac{p\{k=3\}}{p\{k=2\}}=\frac{n-2}3\frac{\theta}{1-\theta},
\]&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;from which we get&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;math display&quot;&gt;\[
\theta = \frac{1}{1+\frac{n-2}3\frac{p\{k=2\}}{p\{k=3\}}}.
\]&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Next, we observe that &lt;span
class=&quot;math inline&quot;&gt;\(p\{k=2\}/p\{k=3\}\)&lt;/span&gt; can be estimated as
&lt;span class=&quot;math inline&quot;&gt;\(m_2/m_3\)&lt;/span&gt;, so&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;math display&quot;&gt;\[
\theta \approx \frac{1}{1+\frac{n-2}3\frac{m_2}{m_3}}.
\]&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Then our quantity of interest is&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;math display&quot;&gt;\[
\begin{split}
m &amp;amp; = m_1+m_2+\ldots+m_n \\
&amp;amp; = \frac{m_2}{p\{k=2\}}\cdot p\{k\geq 1\}\\
&amp;amp; = \frac{2m_2(1-\theta^n)}{n(n-1)\theta^2(1-\theta)^{n-2}}.
\end{split}
\]&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Let’s test this using a simulation.&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb1&quot;&gt;&lt;pre class=&quot;sourceCode r&quot;&gt;&lt;code class=&quot;sourceCode r&quot;&gt;&lt;span id=&quot;cb1-1&quot;&gt;&lt;a href=&quot;#cb1-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;fu&quot;&gt;set.seed&lt;/span&gt;(&lt;span class=&quot;dv&quot;&gt;2018&lt;/span&gt;)&lt;/span&gt;
&lt;span id=&quot;cb1-2&quot;&gt;&lt;a href=&quot;#cb1-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;co&quot;&gt;# number of unique events&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-3&quot;&gt;&lt;a href=&quot;#cb1-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;u &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;40000&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-4&quot;&gt;&lt;a href=&quot;#cb1-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;co&quot;&gt;# number of recurring events (to be re-calculated later)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-5&quot;&gt;&lt;a href=&quot;#cb1-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;m &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;30000&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-6&quot;&gt;&lt;a href=&quot;#cb1-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;co&quot;&gt;# n, the maximum occurrences of a single event&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-7&quot;&gt;&lt;a href=&quot;#cb1-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;n &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;15&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-8&quot;&gt;&lt;a href=&quot;#cb1-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;co&quot;&gt;# rate of occurrence of an event&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-9&quot;&gt;&lt;a href=&quot;#cb1-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;theta &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;fl&quot;&gt;0.23&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-10&quot;&gt;&lt;a href=&quot;#cb1-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;co&quot;&gt;# occurrence data&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-11&quot;&gt;&lt;a href=&quot;#cb1-11&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;occs &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;rbinom&lt;/span&gt;(m, n, theta)&lt;/span&gt;
&lt;span id=&quot;cb1-12&quot;&gt;&lt;a href=&quot;#cb1-12&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;co&quot;&gt;# remove zero occurrences, as they are unobservable&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-13&quot;&gt;&lt;a href=&quot;#cb1-13&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;occs &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; occs[occs &lt;span class=&quot;sc&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;0&lt;/span&gt;]&lt;/span&gt;
&lt;span id=&quot;cb1-14&quot;&gt;&lt;a href=&quot;#cb1-14&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;(m &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;length&lt;/span&gt;(occs))&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;pre&gt;&lt;code&gt;## [1] 29406&lt;/code&gt;&lt;/pre&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb3&quot;&gt;&lt;pre class=&quot;sourceCode r&quot;&gt;&lt;code class=&quot;sourceCode r&quot;&gt;&lt;span id=&quot;cb3-1&quot;&gt;&lt;a href=&quot;#cb3-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;co&quot;&gt;# mix in the non-recurring events&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-2&quot;&gt;&lt;a href=&quot;#cb3-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;occs &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;sample&lt;/span&gt;(&lt;span class=&quot;fu&quot;&gt;c&lt;/span&gt;(occs, &lt;span class=&quot;fu&quot;&gt;rep&lt;/span&gt;(&lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;, u)))&lt;/span&gt;
&lt;span id=&quot;cb3-3&quot;&gt;&lt;a href=&quot;#cb3-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;co&quot;&gt;# m_k, number of events that occurred k times&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-4&quot;&gt;&lt;a href=&quot;#cb3-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;(m_k &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;table&lt;/span&gt;(occs))&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;pre&gt;&lt;code&gt;## occs
##     1     2     3     4     5     6     7     8     9    10    11 
## 42689  5581  7310  6367  4199  2139   800   235    66    17     3&lt;/code&gt;&lt;/pre&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb5&quot;&gt;&lt;pre class=&quot;sourceCode r&quot;&gt;&lt;code class=&quot;sourceCode r&quot;&gt;&lt;span id=&quot;cb5-1&quot;&gt;&lt;a href=&quot;#cb5-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;co&quot;&gt;# now, apply our estimation algorithm:&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-2&quot;&gt;&lt;a href=&quot;#cb5-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;(theta_est &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;sc&quot;&gt;/&lt;/span&gt;(&lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;sc&quot;&gt;+&lt;/span&gt;(n&lt;span class=&quot;dv&quot;&gt;-2&lt;/span&gt;)&lt;span class=&quot;sc&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;3&lt;/span&gt; &lt;span class=&quot;sc&quot;&gt;*&lt;/span&gt; m_k[[&lt;span class=&quot;st&quot;&gt;&amp;quot;2&amp;quot;&lt;/span&gt;]]&lt;span class=&quot;sc&quot;&gt;/&lt;/span&gt;m_k[[&lt;span class=&quot;st&quot;&gt;&amp;quot;3&amp;quot;&lt;/span&gt;]]))&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;pre&gt;&lt;code&gt;## [1] 0.2321052&lt;/code&gt;&lt;/pre&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb7&quot;&gt;&lt;pre class=&quot;sourceCode r&quot;&gt;&lt;code class=&quot;sourceCode r&quot;&gt;&lt;span id=&quot;cb7-1&quot;&gt;&lt;a href=&quot;#cb7-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;(m_est &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; (&lt;span class=&quot;dv&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;sc&quot;&gt;*&lt;/span&gt;m_k[[&lt;span class=&quot;st&quot;&gt;&amp;quot;2&amp;quot;&lt;/span&gt;]]&lt;span class=&quot;sc&quot;&gt;*&lt;/span&gt;(&lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;sc&quot;&gt;-&lt;/span&gt;theta_est&lt;span class=&quot;sc&quot;&gt;**&lt;/span&gt;n)) &lt;span class=&quot;sc&quot;&gt;/&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb7-2&quot;&gt;&lt;a href=&quot;#cb7-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;        (n&lt;span class=&quot;sc&quot;&gt;*&lt;/span&gt;(n&lt;span class=&quot;dv&quot;&gt;-1&lt;/span&gt;)&lt;span class=&quot;sc&quot;&gt;*&lt;/span&gt;theta_est&lt;span class=&quot;sc&quot;&gt;**&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;sc&quot;&gt;*&lt;/span&gt;(&lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;sc&quot;&gt;-&lt;/span&gt;theta_est)&lt;span class=&quot;sc&quot;&gt;**&lt;/span&gt;(n&lt;span class=&quot;dv&quot;&gt;-2&lt;/span&gt;)))&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;pre&gt;&lt;code&gt;## [1] 30565.44&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So we estimated the occurrence rate &lt;span
class=&quot;math inline&quot;&gt;\(\theta\)&lt;/span&gt; as 0.232 (true value 0.23) and the
number of observed recurring events as 30565 (true value 29406). Pretty
good. For smaller sample sizes, the estimates will be not as accurate
but hopefully still useful.&lt;/p&gt;
&lt;h2 id=&quot;the-poisson-model&quot;&gt;The Poisson model&lt;/h2&gt;
&lt;p&gt;The derivation is analogous for the Poisson model.&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;math display&quot;&gt;\[\begin{align*}
p\{k=2\} = \frac{\lambda^2e^{-\lambda}}2; \\
p\{k=3\} = \frac{\lambda^3e^{-\lambda}}6;
\end{align*}\]&lt;/span&gt; &lt;span class=&quot;math display&quot;&gt;\[
\frac{p\{k=3\}}{p\{k=2\}}=\frac{\lambda}3;
\]&lt;/span&gt; &lt;span class=&quot;math display&quot;&gt;\[
\begin{split}
\lambda &amp;amp; = 3\cdot \frac{p\{k=3\}}{p\{k=2\}} \\
&amp;amp; \approx 3\cdot\frac{m_3}{m_2};
\end{split}
\]&lt;/span&gt; &lt;span class=&quot;math display&quot;&gt;\[
\begin{split}
m &amp;amp; = m_1+m_2+\ldots+m_n \\
&amp;amp; = \frac{m_2}{p\{k=2\}}\cdot p\{k\geq 1\}\\
&amp;amp; = \frac{2m_2(e^{\lambda}-1)}{\lambda^2}.
\end{split}
\]&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Simulation:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb9&quot;&gt;&lt;pre class=&quot;sourceCode r&quot;&gt;&lt;code class=&quot;sourceCode r&quot;&gt;&lt;span id=&quot;cb9-1&quot;&gt;&lt;a href=&quot;#cb9-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;fu&quot;&gt;set.seed&lt;/span&gt;(&lt;span class=&quot;dv&quot;&gt;2018&lt;/span&gt;)&lt;/span&gt;
&lt;span id=&quot;cb9-2&quot;&gt;&lt;a href=&quot;#cb9-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;co&quot;&gt;# number of unique events&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb9-3&quot;&gt;&lt;a href=&quot;#cb9-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;u &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;40000&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb9-4&quot;&gt;&lt;a href=&quot;#cb9-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;co&quot;&gt;# number of recurring events (to be re-calculated later)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb9-5&quot;&gt;&lt;a href=&quot;#cb9-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;m &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;30000&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb9-6&quot;&gt;&lt;a href=&quot;#cb9-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;co&quot;&gt;# rate of occurrence of an event&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb9-7&quot;&gt;&lt;a href=&quot;#cb9-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;lambda &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;fl&quot;&gt;1.6&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb9-8&quot;&gt;&lt;a href=&quot;#cb9-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;co&quot;&gt;# occurrence data&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb9-9&quot;&gt;&lt;a href=&quot;#cb9-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;occs &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;rpois&lt;/span&gt;(m, lambda)&lt;/span&gt;
&lt;span id=&quot;cb9-10&quot;&gt;&lt;a href=&quot;#cb9-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;co&quot;&gt;# remove zero occurrences, as they are unobservable&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb9-11&quot;&gt;&lt;a href=&quot;#cb9-11&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;occs &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; occs[occs &lt;span class=&quot;sc&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;0&lt;/span&gt;]&lt;/span&gt;
&lt;span id=&quot;cb9-12&quot;&gt;&lt;a href=&quot;#cb9-12&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;(m &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;length&lt;/span&gt;(occs))&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;pre&gt;&lt;code&gt;## [1] 23882&lt;/code&gt;&lt;/pre&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb11&quot;&gt;&lt;pre class=&quot;sourceCode r&quot;&gt;&lt;code class=&quot;sourceCode r&quot;&gt;&lt;span id=&quot;cb11-1&quot;&gt;&lt;a href=&quot;#cb11-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;co&quot;&gt;# mix in the non-recurring events&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb11-2&quot;&gt;&lt;a href=&quot;#cb11-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;occs &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;sample&lt;/span&gt;(&lt;span class=&quot;fu&quot;&gt;c&lt;/span&gt;(occs, &lt;span class=&quot;fu&quot;&gt;rep&lt;/span&gt;(&lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;, u)))&lt;/span&gt;
&lt;span id=&quot;cb11-3&quot;&gt;&lt;a href=&quot;#cb11-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;co&quot;&gt;# m_k, number of events that occurred k times&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb11-4&quot;&gt;&lt;a href=&quot;#cb11-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;(m_k &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;table&lt;/span&gt;(occs))&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;pre&gt;&lt;code&gt;## occs
##     1     2     3     4     5     6     7     8     9 
## 49744  7669  4090  1667   521   145    31    12     3&lt;/code&gt;&lt;/pre&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb13&quot;&gt;&lt;pre class=&quot;sourceCode r&quot;&gt;&lt;code class=&quot;sourceCode r&quot;&gt;&lt;span id=&quot;cb13-1&quot;&gt;&lt;a href=&quot;#cb13-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;co&quot;&gt;# now, apply our estimation algorithm:&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb13-2&quot;&gt;&lt;a href=&quot;#cb13-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;(lambda_est &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;3&lt;/span&gt; &lt;span class=&quot;sc&quot;&gt;*&lt;/span&gt; m_k[[&lt;span class=&quot;st&quot;&gt;&amp;quot;3&amp;quot;&lt;/span&gt;]]&lt;span class=&quot;sc&quot;&gt;/&lt;/span&gt;m_k[[&lt;span class=&quot;st&quot;&gt;&amp;quot;2&amp;quot;&lt;/span&gt;]])&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;pre&gt;&lt;code&gt;## [1] 1.599948&lt;/code&gt;&lt;/pre&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb15&quot;&gt;&lt;pre class=&quot;sourceCode r&quot;&gt;&lt;code class=&quot;sourceCode r&quot;&gt;&lt;span id=&quot;cb15-1&quot;&gt;&lt;a href=&quot;#cb15-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;(m_est &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; (&lt;span class=&quot;dv&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;sc&quot;&gt;*&lt;/span&gt;m_k[[&lt;span class=&quot;st&quot;&gt;&amp;quot;2&amp;quot;&lt;/span&gt;]]&lt;span class=&quot;sc&quot;&gt;*&lt;/span&gt;(&lt;span class=&quot;fu&quot;&gt;exp&lt;/span&gt;(lambda_est)&lt;span class=&quot;sc&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;)) &lt;span class=&quot;sc&quot;&gt;/&lt;/span&gt; lambda&lt;span class=&quot;sc&quot;&gt;**&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;2&lt;/span&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;pre&gt;&lt;code&gt;## [1] 23682.68&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Again, extremely accurate for large sample sizes: we estimated the
occurrence rate as 1.599948 (true value 1.6) and the number of observed
recurring events as 23682.68 (true value 23882).&lt;/p&gt;
&lt;h2 id=&quot;what-about-m_0&quot;&gt;What about &lt;span
class=&quot;math inline&quot;&gt;\(m_0\)&lt;/span&gt;?&lt;/h2&gt;
&lt;p&gt;In the above calculations, I did not include &lt;span
class=&quot;math inline&quot;&gt;\(m_0\)&lt;/span&gt; (the numer of unobserved but
recurring events) in the definition of &lt;span
class=&quot;math inline&quot;&gt;\(m\)&lt;/span&gt;. While it is trivial to include &lt;span
class=&quot;math inline&quot;&gt;\(m_0\)&lt;/span&gt;, there are good reasons not to.&lt;/p&gt;
&lt;p&gt;The first reason is practical: &lt;span class=&quot;math inline&quot;&gt;\(m\)&lt;/span&gt;
as defined can be used to estimate the &lt;em&gt;fraction&lt;/em&gt; of recurring
events (vs. unique ones); just divide &lt;span
class=&quot;math inline&quot;&gt;\(m\)&lt;/span&gt; by the total number of observed
events.&lt;/p&gt;
&lt;p&gt;The other reason is theoretical: it is not even clear what &lt;span
class=&quot;math inline&quot;&gt;\(m_0\)&lt;/span&gt; means. I like how Bunge et al. (2014)
put it:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Consider the following metaphor or allegory (Böhning &amp;amp; Schön
2005). We go to a freeway interchange and record the numbers of
occupants, including the drivers, of the passing cars, for a fixed
period of time, e.g., during the daylight hours of a given day. In
principle, we could then extract frequency count data: &lt;span
class=&quot;math inline&quot;&gt;\(f_1\)&lt;/span&gt; = the number of cars with one
occupant, &lt;span class=&quot;math inline&quot;&gt;\(f_2\)&lt;/span&gt; = the number with
two, and so forth. From this data, we could in principle compute a
statistical estimate of &lt;span class=&quot;math inline&quot;&gt;\(f_0\)&lt;/span&gt; , the
number of cars with zero occupants, i.e., cars not presently being
driven, and hence the total number of cars in existence, but (apart from
many other potential objections to this procedure) cars in existence
where? That is, what is the target population? Is it all cars that might
pass by our interchange, which could be all cars in North America, or
just some local subset thereof? The answer is unclear. The reader may
object that no one would carry out such a study, but it is not too
different from the ocean-sampling example discussed above. In that
setting, what is the microbial population under study? All microbial
organisms that may enter the 1-liter collection bottle, or some more
restricted subpopulation?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;
&lt;p&gt;A very similar problem arises in microbial ecology; an excellent
review on this is:&lt;/p&gt;
&lt;p&gt;&lt;a
href=&quot;https://www.annualreviews.org/doi/abs/10.1146/annurev-statistics-022513-115654&quot;&gt;John
Bunge, Amy Willis, Fiona Walsh. (2014) Estimating the Number of Species
in Microbial Diversity Studies.&lt;/a&gt;&lt;/p&gt;
</description>
                        <pubDate>Wed, 22 Aug 2018 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2018-08-22-estimate-recurring-events</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2018-08-22-estimate-recurring-events.html</guid>
                </item>
        
                <item>
                        <title>logit() and logistic() functions in R</title>
                        <description>&lt;p&gt;In statistics, a pair of standard functions logit() and logistic()
are defined as follows:&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;math display&quot;&gt;\[
\begin{align*}
\operatorname{logit}(p) &amp;amp;= \log\frac{p}{1-p}; \\
\operatorname{logistic}(x) &amp;amp;= \frac{1}{1+\exp(-x)}.
\end{align*}
\]&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Given the ubiquity of these functions, it may be puzzling and
frustrating for an R user that there are no pre-defined functions
&lt;code&gt;logit()&lt;/code&gt; and &lt;code&gt;logistic()&lt;/code&gt; in R.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt; logit(0.6)
Error in logit(0.6) : could not find function &amp;quot;logit&amp;quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Some CRAN packages define this function, and some users even import
these packages for the sole reason to have access to logit() and/or
logistic(). Others define them directly via log() and exp().&lt;/p&gt;
&lt;p&gt;All this is unnecessary: the standard &lt;code&gt;stats&lt;/code&gt; package
actually defines these functions, just under different names. logit()
and logistic() are the quantile and cumulative distribution functions
for the logistic distribution, so in line with R’s conventions for
probability distributions, they are called &lt;code&gt;qlogis()&lt;/code&gt; and
&lt;code&gt;plogis()&lt;/code&gt;, respectively.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt; qlogis(0.6) # logit
[1] 0.4054651
&amp;gt; plogis(0.4054651) # logistic
[1] 0.6&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If you still prefer to use the familiar names logit() and logistic()
in your code, simply include in your script&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;logit &amp;lt;- qlogis
logistic &amp;lt;- plogis&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;One advantage of using these standard functions over defining your
own or importing some random CRAN package is that they can work on the
log scale, by setting &lt;code&gt;log.p = TRUE&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt; qlogis(log(0.6), log.p = TRUE)
[1] 0.4054651&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Working with log-probabilities is often necessary to avoid underflow,
and implementing logit() and logistic() that work accurately on the log
scale is not trivial; see &lt;a
href=&quot;https://cran.r-project.org/web/packages/Rmpfr/vignettes/log1mexp-note.pdf&quot;&gt;Accurately
Computing &lt;span class=&quot;math inline&quot;&gt;\(\log(1-\exp(-|a|))\)&lt;/span&gt;&lt;/a&gt;
for the details. You can see how these functions are implemented in R in
&lt;code&gt;src/nmath/qlogis.c&lt;/code&gt; and &lt;code&gt;src/nmath/plogis.c&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;And while we’re at it, here’s another trick. Let’s say you are
working with probabilities very close to 1. Then the appropriate
representation is not &lt;span class=&quot;math inline&quot;&gt;\(\log p\)&lt;/span&gt; but
&lt;span class=&quot;math inline&quot;&gt;\(\log (1-p)\)&lt;/span&gt;. To convert a
probability from a log-complement scale to the logit scale, use
&lt;code&gt;lower.tail = FALSE&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt; qlogis(-3, log.p = TRUE, lower.tail = FALSE)
[1] 2.948931&lt;/code&gt;&lt;/pre&gt;
</description>
                        <pubDate>Sat, 11 Aug 2018 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2018-08-11-logit-logistic-r</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2018-08-11-logit-logistic-r.html</guid>
                </item>
        
                <item>
                        <title>Can you cheat the Brier score?</title>
                        <description>&lt;p&gt;The Brier score is a common way of judging probabilistic forecasts.
If you have several people or teams each giving probabilities to various
events, you can judge how well they are doing by comparing their Brier
scores: lower scores correspond to more accurate predictions.&lt;/p&gt;
&lt;p&gt;However, there is a critical assumption behind the Brier score: that
all forecasters compete on the same set of events. Some questions are
easier to predict than others. And I’m &lt;em&gt;not&lt;/em&gt; talking about the
domain-specific difficulty—the sort of difficulty that arises when one
wants to predict whether there will be a revolution in Turkey without
knowing much about the Turkish politics.&lt;/p&gt;
&lt;p&gt;It turns out that the difficulty of achieving a certain Brier score
is directly related to the actual probability of the event. Intuitively
we already understand that: it is easier to “predict” whether a plane
will crash (it probably won’t) than to predict whether it will arrive
late (who knows?).&lt;/p&gt;
&lt;p&gt;Except here we are dealing with &lt;em&gt;probabilistic&lt;/em&gt; predictions
(not a rigid yes or no) and a specific scoring rule (the Brier score),
so our intuitions do not necessarily transfer. And yet the basic result
is the same: it is easier to achieve a low (i.e. good) Brier score
betting on highly probable and highly improbable events than betting on
uncertain events.&lt;/p&gt;
&lt;p&gt;What made me look into this was &lt;a
href=&quot;http://rationallyspeakingpodcast.org/show/rs-214-anthony-aguirre-on-predicting-the-future-of-science-a.html&quot;&gt;this
episode of the Rationally Speaking podcast&lt;/a&gt;, where Julia Galef speaks
with Anthony Aguirre about his prediction platform Metaculus.&lt;/p&gt;
&lt;p&gt;At one point the dialogue goes as follows:&lt;/p&gt;
&lt;table class=&quot;dialogue&quot;&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;Julia:&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;Oh, how do you measure how well it works?&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;Anthony:&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;[…] So looking over sort of the last half year or so, since December
1st, for example… If you ask for how many predictions was Metaculus on
the right side of 50% — above 50% if it happened or below 50% if it
didn’t happen — that happens 77 out of 81 times the question resolved,
so that’s quite good.&lt;/p&gt;
&lt;p&gt;And some of the aficionados will know about Brier scores. That’s sort
of the fairly easy to understand way to do it, which is that you assign
a zero if something doesn’t happen, and a one if something does happen.
Then you take the difference between the predicted probability and that
number. So if you predict at 20% and it didn’t happen, you’d take that
as a .2, or if it’s 80% and it does happen and that’s also a .2, because
it’s a difference between the 80% and a one, and then you square that
number.&lt;/p&gt;
&lt;p&gt;So Brier scores can run from basically zero to one, where low numbers
are good. And if you calculate that for that same set of 80 questions,
it’s .072, which is a pretty good score.&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;Julia:&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;Yeah, I mean I don’t really have a frame of reference — like, I don’t
know what, an average college educated person guessing about these
questions would be expected to guess, or to get for their Brier score.
But it certainly seems low.&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;Anthony:&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;So that’s something that you can sort of … So, some references are a
.25 is what you would get if you guessed 50% for everything. So that’s
sort of totally uncertain. A .33 is what you would get if you just
randomly assigned a probability between zero and one for everything.
It’s slightly different things.&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;p&gt;If you pay attention, there’s already a hint of the problem in this
short exchange. You can get a Brier score of .25 quite easily by always
predicting 50%. But if the &lt;em&gt;true&lt;/em&gt; probability is indeed 50%, then
you &lt;em&gt;have to&lt;/em&gt; predict 50%—any other prediction will get you an
even worse score.&lt;/p&gt;
&lt;p&gt;Say I set up a platform analogous to Metaculus—I’ll call it Metaculus
Prime—and want to beat Metaculus’s Brier score. All I’d need to do is to
formulate slightly different versions of Metaculus questions. Currently,
the #1 question on Metaculus is this: “Will SpaceX land people on Mars
prior to 2030?” On Metaculus Prime, I’ll also allow betting on SpaceX
landing on Mars, except I’ll ask “Will SpaceX land people on Mars prior
to 2020?”. Because the answer to this modified question is more certain,
a person of the same predictive skill would be expected to score better
on it than on the original, less certain question.&lt;/p&gt;
&lt;p&gt;When predicting the more certain events, one still has an incentive
to get the exact probability right (to the extent such a thing exists).
But for a given difference between the true and predicted probabilities,
there is an extra penalty for probabilities close to 0.5, as I
demonstrate below.&lt;/p&gt;
&lt;p&gt;To be clear, this is not to criticize Anthony—it was really
interesting for me to find out Metaculus’s consensus Brier score, and it
doesn’t look at all like he’s manipulating the questions to get a low
Brier score. But we should also recognize that the Brier score is not a
valid metric to compare forecasters who compete on different questions
or different platforms.&lt;/p&gt;
&lt;p&gt;It is also interesting to think about how we should design the
prediction questions. In a question like “Will the number of electric
cars in the world be greater than &lt;span class=&quot;math inline&quot;&gt;\(X\)&lt;/span&gt;
by the end of 2020”, how should we pick &lt;span
class=&quot;math inline&quot;&gt;\(X\)&lt;/span&gt;? If &lt;span
class=&quot;math inline&quot;&gt;\(X\)&lt;/span&gt; is very high or very low, the outcome
will be obvious, and there will also be an incentive to make more
extreme predictions (closer to 0 or 1 than warranted) since you’re
unlikely to be proven wrong in the short term.&lt;/p&gt;
&lt;p&gt;On the other hand, pick &lt;span class=&quot;math inline&quot;&gt;\(X\)&lt;/span&gt; “right
in the middle”, and the best Brier score anyone can achieve on average
becomes the unimpressive 0.25.&lt;/p&gt;
&lt;h2 id=&quot;mathematical-details&quot;&gt;Mathematical details&lt;/h2&gt;
&lt;p&gt;Consider an event &lt;span class=&quot;math inline&quot;&gt;\(X\)&lt;/span&gt; that may
happen &lt;span class=&quot;math inline&quot;&gt;\((X=1)\)&lt;/span&gt; with probability p and
not happen &lt;span class=&quot;math inline&quot;&gt;\((X=0)\)&lt;/span&gt; with probability
&lt;span class=&quot;math inline&quot;&gt;\(1-p\)&lt;/span&gt;. Say you predict the
probability of &lt;span class=&quot;math inline&quot;&gt;\(X\)&lt;/span&gt; happening being
&lt;span class=&quot;math inline&quot;&gt;\(q\)&lt;/span&gt;. Then the Brier score is
calculated as &lt;span class=&quot;math inline&quot;&gt;\((X-q)^2\)&lt;/span&gt;. For multiple
events, take the average of the individual Brier scores.&lt;/p&gt;
&lt;p&gt;The expectation of &lt;span class=&quot;math inline&quot;&gt;\((X-q)^2\)&lt;/span&gt;
is&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;math display&quot;&gt;\[\begin{equation}
\operatorname{E}[(X-q)^2] = (p-q)^2+\operatorname{Var}(X).
\label{eq1}
\end{equation}\]&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;For a given event &lt;span class=&quot;math inline&quot;&gt;\(X\)&lt;/span&gt;, &lt;span
class=&quot;math inline&quot;&gt;\(\operatorname{Var}(X)\)&lt;/span&gt; is a constant, and
to minimize the Brier score you should pick &lt;span
class=&quot;math inline&quot;&gt;\(q=p\)&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;But if you have a choice of which events &lt;span
class=&quot;math inline&quot;&gt;\(X\)&lt;/span&gt; to bet on, it also makes sense to try
and minimize the second term, &lt;span
class=&quot;math inline&quot;&gt;\(\operatorname{Var}(X)\)&lt;/span&gt;. The variance of a
binary (“Bernoulli”) variable &lt;span class=&quot;math inline&quot;&gt;\(X\)&lt;/span&gt; is
given by &lt;span
class=&quot;math inline&quot;&gt;\(\operatorname{Var}(X)=p(1-p)\)&lt;/span&gt;. It is
maximal when &lt;span class=&quot;math inline&quot;&gt;\(p=0.5\)&lt;/span&gt; and falls as
&lt;span class=&quot;math inline&quot;&gt;\(p\)&lt;/span&gt; moves towards 0 or 1.&lt;/p&gt;
&lt;figure&gt;
&lt;img src=&quot;/img/bernoulli-variance.svg&quot; style=&quot;max-height: 400px;&quot;
alt=&quot;The variance of a 0-1 variable X as a function of its mean (the probability of 1) p&quot; /&gt;
&lt;figcaption aria-hidden=&quot;true&quot;&gt;The variance of a 0-1 variable &lt;span
class=&quot;math inline&quot;&gt;\(X\)&lt;/span&gt; as a function of its mean (the
probability of 1) &lt;span class=&quot;math inline&quot;&gt;\(p\)&lt;/span&gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h2 id=&quot;additional-considerations&quot;&gt;Additional considerations&lt;/h2&gt;
&lt;p&gt;There are two other considerations that exacerbate this effect. First
is that a given absolute error in probabilities—say, 5 percentage
points—is actually &lt;em&gt;more&lt;/em&gt; severe for probabilities closer to 0 or
1, so if anything, the errors should be penalized more for highly
certain events, not less. This could be seen, for instance, on the
log-odds scale: the difference between 0.6 and 0.65 is only 0.21, while
the difference between 0.9 and 0.95 is 0.75.&lt;/p&gt;
&lt;p&gt;The other consideration is that if I tend to assign the probability
of 1 for 99% events—a serious error, if you ask me—it will take quite a
few predictions to prove me wrong. In the short term, I will actually be
rewarded for making more “certain” forecasts for rare events.&lt;/p&gt;
&lt;p&gt;Most of this article assumes that there exists some inherent
uncertainty in the predicted event. The alternative view is that most of
events (barring quantum experiments and chaotic systems) can be
predicted exactly by a skilled enough team and given enough resources.
While in this case it doesn’t make sense to talk about the true
probability of an event, the fact that different events may be of
different difficulty becomes even more obvious.&lt;/p&gt;
&lt;h2 id=&quot;updates-from-2021&quot;&gt;Updates from 2021&lt;/h2&gt;
&lt;p&gt;See also:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a
href=&quot;https://astralcodexten.substack.com/p/mantic-monday-scoring-rule-controversy&quot;
class=&quot;uri&quot;&gt;https://astralcodexten.substack.com/p/mantic-monday-scoring-rule-controversy&lt;/a&gt;,
and links therein, in particular&lt;/li&gt;
&lt;li&gt;&lt;a
href=&quot;https://metaculus.medium.com/a-primer-on-the-metaculus-scoring-rule-eb9a974cd204&quot;
class=&quot;uri&quot;&gt;https://metaculus.medium.com/a-primer-on-the-metaculus-scoring-rule-eb9a974cd204&lt;/a&gt;
by Anthony Aguirre himself.&lt;/li&gt;
&lt;/ul&gt;
</description>
                        <pubDate>Thu, 09 Aug 2018 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2018-08-09-cheat-brier-score</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2018-08-09-cheat-brier-score.html</guid>
                </item>
        
                <item>
                        <title>Probability of a regex occurrence</title>
                        <description>&lt;p&gt;Given a regular expression &lt;span class=&quot;math inline&quot;&gt;\(R\)&lt;/span&gt; and
a random string &lt;span class=&quot;math inline&quot;&gt;\(L\)&lt;/span&gt; of length &lt;span
class=&quot;math inline&quot;&gt;\(n\)&lt;/span&gt;, what is the probability that &lt;span
class=&quot;math inline&quot;&gt;\(R\)&lt;/span&gt; matches somewhere in &lt;span
class=&quot;math inline&quot;&gt;\(L\)&lt;/span&gt;?&lt;/p&gt;
&lt;p&gt;This seems like an intimidating problem at first, but I was surprised
how easy it becomes after a couple of insights.&lt;/p&gt;
&lt;p&gt;The first insight is to turn a regex into a &lt;a
href=&quot;https://en.wikipedia.org/wiki/Deterministic_finite_automaton&quot;&gt;DFA&lt;/a&gt;.
This moves us from &lt;em&gt;“how can I possibly know whether a regex
matches?”&lt;/em&gt; to &lt;em&gt;“feed the string to the automaton and see if it
ends up in an accepting state”&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Still, the DFA can be anything at all — how do we know the
probability of ending up in an accepting state? The second insight is to
ascribe probabilities to the edges (transitions) of the DFA and observe
that this turns it into a Markov chain&lt;a href=&quot;#fn1&quot;
class=&quot;footnote-ref&quot; id=&quot;fnref1&quot;
role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;1&lt;/sup&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Why is that helpful? Because a Markov chain can be represented by its
&lt;a href=&quot;https://en.wikipedia.org/wiki/Stochastic_matrix&quot;&gt;transition
matrix&lt;/a&gt; &lt;span class=&quot;math inline&quot;&gt;\(P\)&lt;/span&gt;, and the probability
of getting from any state &lt;span class=&quot;math inline&quot;&gt;\(a\)&lt;/span&gt; to any
state &lt;span class=&quot;math inline&quot;&gt;\(b\)&lt;/span&gt; can be computed in &lt;a
href=&quot;https://en.wikipedia.org/wiki/Exponentiation_by_squaring&quot;&gt;logarithmic
time&lt;/a&gt; by computing &lt;span class=&quot;math inline&quot;&gt;\(P^n_{ab}\)&lt;/span&gt;, the
&lt;span class=&quot;math inline&quot;&gt;\(a,b\)&lt;/span&gt;-th element of the &lt;span
class=&quot;math inline&quot;&gt;\(n\)&lt;/span&gt;-th power of the matrix &lt;span
class=&quot;math inline&quot;&gt;\(P\)&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;So how do we assign the probabilities to DFA transitions? If all
characters are equally likely, &lt;span
class=&quot;math inline&quot;&gt;\(P_{ab}\)&lt;/span&gt; is simply the number of characters
that move the DFA from state &lt;span class=&quot;math inline&quot;&gt;\(a\)&lt;/span&gt; to
state &lt;span class=&quot;math inline&quot;&gt;\(b\)&lt;/span&gt; divided by the number of
all possible characters. More generally, if every letter &lt;span
class=&quot;math inline&quot;&gt;\(l\)&lt;/span&gt; has a fixed probability &lt;span
class=&quot;math inline&quot;&gt;\(p_l\)&lt;/span&gt;, we compute &lt;span
class=&quot;math display&quot;&gt;\[
P_{ab}=\sum_{a\overset{l}{\rightarrow} b}p_l,
\]&lt;/span&gt; where the summation is over all characters &lt;span
class=&quot;math inline&quot;&gt;\(l\)&lt;/span&gt; that lead from &lt;span
class=&quot;math inline&quot;&gt;\(a\)&lt;/span&gt; to &lt;span
class=&quot;math inline&quot;&gt;\(b\)&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;And to get the probability of the regex &lt;span
class=&quot;math inline&quot;&gt;\(R\)&lt;/span&gt; matching &lt;em&gt;anywhere inside&lt;/em&gt; the
string as opposed to matching the whole string, replace &lt;span
class=&quot;math inline&quot;&gt;\(R\)&lt;/span&gt; with &lt;span
class=&quot;math inline&quot;&gt;\({.}{*}R{.}{*}\)&lt;/span&gt; before compiling it to a
DFA. Then calculate&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;math display&quot;&gt;\[
\sum_{f\in F} P^n_{sf},
\]&lt;/span&gt; where &lt;span class=&quot;math inline&quot;&gt;\(s\)&lt;/span&gt; is the start
state of the DFA, and &lt;span class=&quot;math inline&quot;&gt;\(F\)&lt;/span&gt; is the set
of accepting states.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/UnkindPartition/motif-stats&quot;&gt;Here’s a
simple implementation&lt;/a&gt; of this algorithm. (The library code supports
full regular expressions over arbitrary finite alphabets, but the
command line tool only accepts simple &lt;a
href=&quot;https://en.wikipedia.org/wiki/Nucleic_acid_notation#IUPAC_notation&quot;&gt;IUPAC&lt;/a&gt;
patterns over the DNA alphabet.)&lt;/p&gt;
&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;
&lt;p&gt;There is nothing new or original here — specialists know how to solve
this and even more involved problems. For these more involved problems,
generating functions are typically used. It’s nice, however, that for
this specific case simple matrix exponentiation suffices.&lt;/p&gt;
&lt;p&gt;For example, &lt;a
href=&quot;https://www.sciencedirect.com/science/article/pii/S030439750100264X&quot;&gt;Nicodème,
Salvy and Flajolet (2002)&lt;/a&gt; show how to use generating functions to
calculate the probability distribution of the number of occurrences of a
regex, both overlapping and non-overlapping, as well as the mean and
variance of that number. They also derive the asymptotics and handle
(first-order) Markov dependencies between the consequtive positions in
&lt;span class=&quot;math inline&quot;&gt;\(L\)&lt;/span&gt;. But for our task — the
probability of a regex occurring at least once — their method
essentially reduces to the one described here.&lt;/p&gt;
&lt;p&gt;&lt;a
href=&quot;https://www.sciencedirect.com/science/article/pii/S0166218X00001955&quot;&gt;Régnier
(2000)&lt;/a&gt; also uses generating functions but explicitly models possible
overlaps between patterns, which allows her to analyze regular
expressions more efficiently than Nicodème et al. (see page 20).&lt;/p&gt;
&lt;p&gt;&lt;a
href=&quot;https://www.biorxiv.org/content/early/2017/10/18/205427&quot;&gt;Filion
2017&lt;/a&gt; is a very accessible introduction to the paradigm of transfer
graphs, which are a bridge between DFAs, transition matrices, and
generating functions.&lt;/p&gt;
&lt;section id=&quot;footnotes&quot; class=&quot;footnotes footnotes-end-of-document&quot;
role=&quot;doc-endnotes&quot;&gt;
&lt;hr /&gt;
&lt;ol&gt;
&lt;li id=&quot;fn1&quot;&gt;&lt;p&gt;Here I assume that different positions in &lt;span
class=&quot;math inline&quot;&gt;\(L\)&lt;/span&gt; are independent.&lt;a href=&quot;#fnref1&quot;
class=&quot;footnote-back&quot; role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</description>
                        <pubDate>Wed, 01 Aug 2018 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2018-08-01-probability-of-regex</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2018-08-01-probability-of-regex.html</guid>
                </item>
        
                <item>
                        <title>Combine ChIP-seq peaks from multiple replicates via consensus voting</title>
                        <description>&lt;p&gt;As in most of biology, having biological replicates in ChIP-seq
experiments is important to ensure &lt;a
href=&quot;https://en.wikipedia.org/wiki/External_validity&quot;&gt;external
validity&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Or, in simpler words, your low-q-value peak from a single sample only
means that the peak was definitely there in this one sample. Without
replicates, you don’t know if this peak is reliably there across samples
or was specific to that one sample at that one time.&lt;/p&gt;
&lt;p&gt;So, in order to know that your results are reliable and can be
expected to replicate in other similar experiments, you should replicate
them yourself on different biological samples. The more diverse your
replicates, the more externally valid your findings. For instance, if
all your replicates come from the same inbred strain, you can conclude
that your findings probably generalize to most individuals in that
strain but may be caused by the strain’s genotype and not generalize to
the whole population.&lt;/p&gt;
&lt;p&gt;But say you do have biological replicates — how do you analyze them?
While tools for &lt;em&gt;differential&lt;/em&gt; analysis of peaks typically know
how to deal with replicates, tools for peak calling (such as MACS) deal
only with a single replicate at a time. This is a problem if you are
only interested in finding transcription factor binding sites.&lt;/p&gt;
&lt;p&gt;Often people seem to resort to either intersecting or taking the
union of all peaks just because it’s very easy to do using bedtools.
However, as &lt;a href=&quot;https://dx.doi.org/10.5936/csbj.201401002&quot;&gt;Yang et
al.&lt;/a&gt; argue, doing so will result in high false negative and false
positive rates, respectively. Instead, they propose a compromise: call a
consensus peak if it’s supported by at least a certain number of
replicates — say, by at least half of them. But unlike simple union or
intersection, there do not appear to be any ready-to-use tools to
perform this kind of analysis.&lt;/p&gt;
&lt;p&gt;So here I’ll explain how to use R/Bioconductor to find regions that
are covered by at least a given number of replicate peaks. Note that my
approach does not correspond directly to any of the 4 approaches
described by Yang et al. Their method results in a smaller number of
wider peaks, but parts of those consensus peaks may have smaller
coverage as shown below.&lt;/p&gt;
&lt;figure&gt;
&lt;img src=&quot;/img/chip-seq-consensus.jpeg&quot;
alt=&quot;Figure adapted from Yang et al. My annotation (in red) shows that, despite the majority vote, part of the consensus region is only supported by 1 out of 3 replicates.&quot; /&gt;
&lt;figcaption aria-hidden=&quot;true&quot;&gt;Figure adapted from Yang et al. My
annotation (in red) shows that, despite the majority vote, part of the
consensus region is only supported by 1 out of 3
replicates.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;This could be a problem when peaks spanning hundreds or thousands of
bp overlap only a little. A better approach would be to first to
identify regions supported by the given number of replicates and then
optionally merge those that are close to each other, which I’ll also
show how to do.&lt;/p&gt;
&lt;p&gt;Of course this is very subjective and arbitrary, and ideally we would
use a robust statistical model instead of a hand-picked threshold. And
there are some tools that attempt this:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a
href=&quot;https://bioconductor.org/packages/release/bioc/html/GenoGAM.html&quot;&gt;GenoGAM&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://mahonylab.org/software/multigps/&quot;&gt;MultiGPS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.ncbi.nlm.nih.gov/pubmed/24894502&quot;&gt;PePr&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a
href=&quot;https://www.ncbi.nlm.nih.gov/pmc/articles/PMC5025614/&quot;&gt;Sierra
Platinum&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/Genometric/MSPC&quot;&gt;MSPC&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I &lt;a href=&quot;https://bioinformatics.chat/genogam&quot;&gt;discussed GenoGAM
with its authors last year&lt;/a&gt;, but I am yet to study and compare the
other ones.&lt;/p&gt;
&lt;!-- start generated output --&gt;
&lt;h2 id=&quot;calling-consensus-peaks-in-bioconductor&quot;&gt;Calling consensus peaks
in Bioconductor&lt;/h2&gt;
&lt;p&gt;First, load the Bioconductor libraries to work with genomic
ranges:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb1&quot;&gt;&lt;pre class=&quot;sourceCode r&quot;&gt;&lt;code class=&quot;sourceCode r&quot;&gt;&lt;span id=&quot;cb1-1&quot;&gt;&lt;a href=&quot;#cb1-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;fu&quot;&gt;library&lt;/span&gt;(rtracklayer)&lt;/span&gt;
&lt;span id=&quot;cb1-2&quot;&gt;&lt;a href=&quot;#cb1-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;fu&quot;&gt;library&lt;/span&gt;(GenomicRanges)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Get the list of &lt;code&gt;.narrowPeak&lt;/code&gt; files in the current
directory. We’ll treat them all as replicates. The same code should work
with &lt;code&gt;.bed&lt;/code&gt; or &lt;code&gt;.gff&lt;/code&gt; files.&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb2&quot;&gt;&lt;pre class=&quot;sourceCode r&quot;&gt;&lt;code class=&quot;sourceCode r&quot;&gt;&lt;span id=&quot;cb2-1&quot;&gt;&lt;a href=&quot;#cb2-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;peak_files &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;list.files&lt;/span&gt;(&lt;span class=&quot;at&quot;&gt;pattern =&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;quot;.*&lt;/span&gt;&lt;span class=&quot;sc&quot;&gt;\\&lt;/span&gt;&lt;span class=&quot;st&quot;&gt;.narrowPeak&amp;quot;&lt;/span&gt;)&lt;/span&gt;
&lt;span id=&quot;cb2-2&quot;&gt;&lt;a href=&quot;#cb2-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;peak_files&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;pre&gt;&lt;code&gt;## [1] &amp;quot;NRF2SFN-Chorley-rep1_bw300_narrow_peaks.narrowPeak&amp;quot;
## [2] &amp;quot;NRF2SFN-Chorley-rep2_bw300_narrow_peaks.narrowPeak&amp;quot;
## [3] &amp;quot;NRF2SFN-Chorley-rep3_bw300_narrow_peaks.narrowPeak&amp;quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Read these files using rtracklayer’s &lt;code&gt;import&lt;/code&gt;
function:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb4&quot;&gt;&lt;pre class=&quot;sourceCode r&quot;&gt;&lt;code class=&quot;sourceCode r&quot;&gt;&lt;span id=&quot;cb4-1&quot;&gt;&lt;a href=&quot;#cb4-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;peak_granges &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;lapply&lt;/span&gt;(peak_files, import)&lt;/span&gt;
&lt;span id=&quot;cb4-2&quot;&gt;&lt;a href=&quot;#cb4-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;peak_granges&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;pre&gt;&lt;code&gt;## [[1]]
## GRanges object with 1415 ranges and 6 metadata columns:
##                seqnames          ranges strand |                                        name
##                   &amp;lt;Rle&amp;gt;       &amp;lt;IRanges&amp;gt;  &amp;lt;Rle&amp;gt; |                                 &amp;lt;character&amp;gt;
##      [1]   NC_000001.11     10041-10186      * |    NRF2SFN-Chorley-rep1_bw300_narrow_peak_1
##      [2]   NC_000001.11   629597-629707      * |    NRF2SFN-Chorley-rep1_bw300_narrow_peak_2
##      [3]   NC_000001.11   630278-630444      * |    NRF2SFN-Chorley-rep1_bw300_narrow_peak_3
##      [4]   NC_000001.11   631154-631304      * |    NRF2SFN-Chorley-rep1_bw300_narrow_peak_4
##      [5]   NC_000001.11   631961-632210      * |    NRF2SFN-Chorley-rep1_bw300_narrow_peak_5
##      ...            ...             ...    ... .                                         ...
##   [1411] NW_017852933.1 1174567-1174677      * | NRF2SFN-Chorley-rep1_bw300_narrow_peak_1411
##   [1412] NW_017852933.1 1593093-1593226      * | NRF2SFN-Chorley-rep1_bw300_narrow_peak_1412
##   [1413] NW_018654708.1   221820-221930      * | NRF2SFN-Chorley-rep1_bw300_narrow_peak_1413
##   [1414] NW_018654713.1     29933-30043      * | NRF2SFN-Chorley-rep1_bw300_narrow_peak_1414
##   [1415] NW_019805500.1     69753-69895      * | NRF2SFN-Chorley-rep1_bw300_narrow_peak_1415
##              score signalValue    pValue    qValue      peak
##          &amp;lt;numeric&amp;gt;   &amp;lt;numeric&amp;gt; &amp;lt;numeric&amp;gt; &amp;lt;numeric&amp;gt; &amp;lt;integer&amp;gt;
##      [1]        27     5.17033   6.91041   2.79078        38
##      [2]        66     3.80497  11.22005   6.63982        82
##      [3]        93     4.31874   14.1121   9.31245        98
##      [4]        50     3.50501   9.46955   5.06445        99
##      [5]        77     4.25812  12.40796   7.76729       174
##      ...       ...         ...       ...       ...       ...
##   [1411]        31     4.58205   7.31183   3.15002        63
##   [1412]       158    10.99692  21.19611  15.89375        50
##   [1413]        60     5.71026  10.64406   6.09574        23
##   [1414]        53     6.15752   9.80128   5.37605        17
##   [1415]        47     5.49846   9.13087    4.7435        78
##   -------
##   seqinfo: 81 sequences from an unspecified genome; no seqlengths
## 
## [[2]]
## GRanges object with 10073 ranges and 6 metadata columns:
##                 seqnames        ranges strand |                                         name
##                    &amp;lt;Rle&amp;gt;     &amp;lt;IRanges&amp;gt;  &amp;lt;Rle&amp;gt; |                                  &amp;lt;character&amp;gt;
##       [1]   NC_000001.11    9913-10101      * |     NRF2SFN-Chorley-rep2_bw300_narrow_peak_1
##       [2]   NC_000001.11 118531-118688      * |     NRF2SFN-Chorley-rep2_bw300_narrow_peak_2
##       [3]   NC_000001.11 175750-175907      * |     NRF2SFN-Chorley-rep2_bw300_narrow_peak_3
##       [4]   NC_000001.11 180786-181117      * |     NRF2SFN-Chorley-rep2_bw300_narrow_peak_4
##       [5]   NC_000001.11 295097-295254      * |     NRF2SFN-Chorley-rep2_bw300_narrow_peak_5
##       ...            ...           ...    ... .                                          ...
##   [10069] NW_019805499.1   41689-41864      * | NRF2SFN-Chorley-rep2_bw300_narrow_peak_10069
##   [10070] NW_019805499.1   42535-42692      * | NRF2SFN-Chorley-rep2_bw300_narrow_peak_10070
##   [10071] NW_019805500.1   15499-15656      * | NRF2SFN-Chorley-rep2_bw300_narrow_peak_10071
##   [10072] NW_019805501.1   42374-42531      * | NRF2SFN-Chorley-rep2_bw300_narrow_peak_10072
##   [10073] NW_019805503.1   32183-32340      * | NRF2SFN-Chorley-rep2_bw300_narrow_peak_10073
##               score signalValue    pValue    qValue      peak
##           &amp;lt;numeric&amp;gt;   &amp;lt;numeric&amp;gt; &amp;lt;numeric&amp;gt; &amp;lt;numeric&amp;gt; &amp;lt;integer&amp;gt;
##       [1]        56     6.82969  10.16471   5.62669       138
##       [2]        30     3.84819   7.00974   3.01917        96
##       [3]        15      2.8959    5.1229   1.53902        65
##       [4]        64     7.20184  11.08078   6.47703        95
##       [5]        25     3.75744   6.16293   2.50373       104
##       ...       ...         ...       ...       ...       ...
##   [10069]        67     5.79181  11.53681   6.76819        34
##   [10070]        30      3.8263   6.76788   3.00398        61
##   [10071]        24     3.74499   6.07139   2.41671       109
##   [10072]        30      3.8263   6.76788   3.00398       115
##   [10073]        30     3.86121   7.17009   3.01917        23
##   -------
##   seqinfo: 250 sequences from an unspecified genome; no seqlengths
## 
## [[3]]
## GRanges object with 5834 ranges and 6 metadata columns:
##                seqnames        ranges strand |                                        name
##                   &amp;lt;Rle&amp;gt;     &amp;lt;IRanges&amp;gt;  &amp;lt;Rle&amp;gt; |                                 &amp;lt;character&amp;gt;
##      [1]   NC_000001.11   75561-75825      * |    NRF2SFN-Chorley-rep3_bw300_narrow_peak_1
##      [2]   NC_000001.11 118452-118776      * |    NRF2SFN-Chorley-rep3_bw300_narrow_peak_2
##      [3]   NC_000001.11 295059-295342      * |    NRF2SFN-Chorley-rep3_bw300_narrow_peak_3
##      [4]   NC_000001.11 376867-377338      * |    NRF2SFN-Chorley-rep3_bw300_narrow_peak_4
##      [5]   NC_000001.11 474500-474783      * |    NRF2SFN-Chorley-rep3_bw300_narrow_peak_5
##      ...            ...           ...    ... .                                         ...
##   [5830] NW_019805495.1 242418-242709      * | NRF2SFN-Chorley-rep3_bw300_narrow_peak_5830
##   [5831] NW_019805495.1 258219-258668      * | NRF2SFN-Chorley-rep3_bw300_narrow_peak_5831
##   [5832] NW_019805496.1 127568-127832      * | NRF2SFN-Chorley-rep3_bw300_narrow_peak_5832
##   [5833] NW_019805499.1   30032-30296      * | NRF2SFN-Chorley-rep3_bw300_narrow_peak_5833
##   [5834] NW_019805500.1     7260-7524      * | NRF2SFN-Chorley-rep3_bw300_narrow_peak_5834
##              score signalValue    pValue    qValue      peak
##          &amp;lt;numeric&amp;gt;   &amp;lt;numeric&amp;gt; &amp;lt;numeric&amp;gt; &amp;lt;numeric&amp;gt; &amp;lt;integer&amp;gt;
##      [1]        30     4.46341   6.72273   3.00157        88
##      [2]        76     7.14145  12.01206   7.62227        66
##      [3]        57     6.52364   9.85515   5.70239        27
##      [4]       225     14.2829  28.09008  22.54761       253
##      [5]        55      6.4522   9.65794    5.5344       181
##      ...       ...         ...       ...       ...       ...
##   [5830]        21     4.07727   5.38735     2.108       182
##   [5831]        42     5.28269   8.11069   4.24385       249
##   [5832]        43     5.35609   8.42216   4.39757        73
##   [5833]        42     5.28269   8.11069   4.24385       104
##   [5834]        30     4.46341   6.72273   3.00157       180
##   -------
##   seqinfo: 170 sequences from an unspecified genome; no seqlengths&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;peak_ranges&lt;/code&gt; is a simple R list with 3 elements, which
individually are &lt;code&gt;GRanges&lt;/code&gt; objects. Now let’s turn this list
into a &lt;code&gt;GRangesList&lt;/code&gt;, which in this case is more convenient
to work with.&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb6&quot;&gt;&lt;pre class=&quot;sourceCode r&quot;&gt;&lt;code class=&quot;sourceCode r&quot;&gt;&lt;span id=&quot;cb6-1&quot;&gt;&lt;a href=&quot;#cb6-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;peak_grangeslist &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;GRangesList&lt;/span&gt;(peak_granges)&lt;/span&gt;
&lt;span id=&quot;cb6-2&quot;&gt;&lt;a href=&quot;#cb6-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;peak_grangeslist&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;pre&gt;&lt;code&gt;## GRangesList object of length 3:
## [[1]] 
## GRanges object with 1415 ranges and 6 metadata columns:
##                seqnames          ranges strand |                                        name
##                   &amp;lt;Rle&amp;gt;       &amp;lt;IRanges&amp;gt;  &amp;lt;Rle&amp;gt; |                                 &amp;lt;character&amp;gt;
##      [1]   NC_000001.11     10041-10186      * |    NRF2SFN-Chorley-rep1_bw300_narrow_peak_1
##      [2]   NC_000001.11   629597-629707      * |    NRF2SFN-Chorley-rep1_bw300_narrow_peak_2
##      [3]   NC_000001.11   630278-630444      * |    NRF2SFN-Chorley-rep1_bw300_narrow_peak_3
##      [4]   NC_000001.11   631154-631304      * |    NRF2SFN-Chorley-rep1_bw300_narrow_peak_4
##      [5]   NC_000001.11   631961-632210      * |    NRF2SFN-Chorley-rep1_bw300_narrow_peak_5
##      ...            ...             ...    ... .                                         ...
##   [1411] NW_017852933.1 1174567-1174677      * | NRF2SFN-Chorley-rep1_bw300_narrow_peak_1411
##   [1412] NW_017852933.1 1593093-1593226      * | NRF2SFN-Chorley-rep1_bw300_narrow_peak_1412
##   [1413] NW_018654708.1   221820-221930      * | NRF2SFN-Chorley-rep1_bw300_narrow_peak_1413
##   [1414] NW_018654713.1     29933-30043      * | NRF2SFN-Chorley-rep1_bw300_narrow_peak_1414
##   [1415] NW_019805500.1     69753-69895      * | NRF2SFN-Chorley-rep1_bw300_narrow_peak_1415
##              score signalValue    pValue    qValue      peak
##          &amp;lt;numeric&amp;gt;   &amp;lt;numeric&amp;gt; &amp;lt;numeric&amp;gt; &amp;lt;numeric&amp;gt; &amp;lt;integer&amp;gt;
##      [1]        27     5.17033   6.91041   2.79078        38
##      [2]        66     3.80497  11.22005   6.63982        82
##      [3]        93     4.31874   14.1121   9.31245        98
##      [4]        50     3.50501   9.46955   5.06445        99
##      [5]        77     4.25812  12.40796   7.76729       174
##      ...       ...         ...       ...       ...       ...
##   [1411]        31     4.58205   7.31183   3.15002        63
##   [1412]       158    10.99692  21.19611  15.89375        50
##   [1413]        60     5.71026  10.64406   6.09574        23
##   [1414]        53     6.15752   9.80128   5.37605        17
##   [1415]        47     5.49846   9.13087    4.7435        78
## 
## ...
## &amp;lt;2 more elements&amp;gt;
## -------
## seqinfo: 299 sequences from an unspecified genome; no seqlengths&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, find the genome regions which are covered by at least 2 of the 3
sets of peaks:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb8&quot;&gt;&lt;pre class=&quot;sourceCode r&quot;&gt;&lt;code class=&quot;sourceCode r&quot;&gt;&lt;span id=&quot;cb8-1&quot;&gt;&lt;a href=&quot;#cb8-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;peak_coverage &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;coverage&lt;/span&gt;(peak_grangeslist)&lt;/span&gt;
&lt;span id=&quot;cb8-2&quot;&gt;&lt;a href=&quot;#cb8-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;peak_coverage&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;pre&gt;&lt;code&gt;## RleList of length 299
## $NC_000001.11
## integer-Rle of length 248946484 with 3023 runs
##   Lengths:   9912    128     61     85  65374    265 ... 220661    275    137     85    197     84
##   Values :      0      1      2      1      0      1 ...      0      1      2      1      2      1
## 
## $NC_000002.12
## integer-Rle of length 242183602 with 1773 runs
##   Lengths:  214478     265  588943     158     260 ...     288   50217     103     159      28
##   Values :       0       1       0       1       0 ...       1       0       1       2       1
## 
## $NC_000003.12
## integer-Rle of length 198174065 with 1492 runs
##   Lengths:    9884     259      73     209     217 ...     158   98693     221    4926     294
##   Values :       0       1       2       3       2 ...       1       0       1       0       1
## 
## $NC_000004.12
## integer-Rle of length 190204610 with 1998 runs
##   Lengths:   9848     94     53    243     44     62 ...   1005     11    162    106  23142    170
##   Values :      0      1      2      3      2      1 ...      0      1      2      1      0      1
## 
## $NC_000005.10
## integer-Rle of length 181450116 with 1874 runs
##   Lengths:    9901       7      97    1388      54 ...     112     158     202    6807    1286
##   Values :       0       1       2       3       2 ...       1       2       1       0       1
## 
## ...
## &amp;lt;294 more elements&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;peak_coverage&lt;/code&gt; is a list of numbers for every single
genome position, encoded into an efficient structure Rle. Now, using the
&lt;code&gt;slice&lt;/code&gt; function, let’s get the regions in the genome where
coverage is at least 2:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb10&quot;&gt;&lt;pre class=&quot;sourceCode r&quot;&gt;&lt;code class=&quot;sourceCode r&quot;&gt;&lt;span id=&quot;cb10-1&quot;&gt;&lt;a href=&quot;#cb10-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;covered_ranges &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;slice&lt;/span&gt;(peak_coverage, &lt;span class=&quot;at&quot;&gt;lower=&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;2&lt;/span&gt;, &lt;span class=&quot;at&quot;&gt;rangesOnly=&lt;/span&gt;T)&lt;/span&gt;
&lt;span id=&quot;cb10-2&quot;&gt;&lt;a href=&quot;#cb10-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;covered_ranges&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;pre&gt;&lt;code&gt;## IRangesList of length 299
## $NC_000001.11
## IRanges object with 154 ranges and 0 metadata columns:
##             start       end     width
##         &amp;lt;integer&amp;gt; &amp;lt;integer&amp;gt; &amp;lt;integer&amp;gt;
##     [1]     10041     10101        61
##     [2]    118531    118688       158
##     [3]    295097    295254       158
##     [4]    377069    377226       158
##     [5]    709516    709673       158
##     ...       ...       ...       ...
##   [150] 228636089 228636238       150
##   [151] 243037096 243037253       158
##   [152] 244523624 244523802       179
##   [153] 248945982 248946118       137
##   [154] 248946204 248946400       197
## 
## ...
## &amp;lt;298 more elements&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is a simple &lt;code&gt;IRangesList&lt;/code&gt; object; let’s covert it to
a &lt;code&gt;GRanges&lt;/code&gt; object:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb12&quot;&gt;&lt;pre class=&quot;sourceCode r&quot;&gt;&lt;code class=&quot;sourceCode r&quot;&gt;&lt;span id=&quot;cb12-1&quot;&gt;&lt;a href=&quot;#cb12-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;covered_granges &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;GRanges&lt;/span&gt;(covered_ranges)&lt;/span&gt;
&lt;span id=&quot;cb12-2&quot;&gt;&lt;a href=&quot;#cb12-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;covered_granges&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;pre&gt;&lt;code&gt;## GRanges object with 1401 ranges and 0 metadata columns:
##                seqnames        ranges strand
##                   &amp;lt;Rle&amp;gt;     &amp;lt;IRanges&amp;gt;  &amp;lt;Rle&amp;gt;
##      [1]   NC_000001.11   10041-10101      *
##      [2]   NC_000001.11 118531-118688      *
##      [3]   NC_000001.11 295097-295254      *
##      [4]   NC_000001.11 377069-377226      *
##      [5]   NC_000001.11 709516-709673      *
##      ...            ...           ...    ...
##   [1397]    NT_187617.1   59572-59732      *
##   [1398] NW_003315930.1   14229-14368      *
##   [1399] NW_003315952.3   57671-57785      *
##   [1400] NW_003315959.1 134807-134820      *
##   [1401] NW_003571050.1 380055-380202      *
##   -------
##   seqinfo: 299 sequences from an unspecified genome; no seqlengths&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And we are done! We can also save these regions as a
&lt;code&gt;.bed&lt;/code&gt; file using rtracklayer’s &lt;code&gt;export&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb14&quot;&gt;&lt;pre class=&quot;sourceCode r&quot;&gt;&lt;code class=&quot;sourceCode r&quot;&gt;&lt;span id=&quot;cb14-1&quot;&gt;&lt;a href=&quot;#cb14-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;fu&quot;&gt;export&lt;/span&gt;(covered_granges, &lt;span class=&quot;st&quot;&gt;&amp;quot;consensus.bed&amp;quot;&lt;/span&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;merging-nearby-peaks&quot;&gt;Merging nearby peaks&lt;/h2&gt;
&lt;p&gt;As I mentioned at the beginning, you might want to merge the peaks
that are close to each other to avoid having many small fragments. In
Bioconductor, you can do that using the &lt;code&gt;min.gapwidth&lt;/code&gt;
parameters to &lt;code&gt;reduce&lt;/code&gt;. For example, this will merge the
peaks that are separated by no more than 30 bp:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb15&quot;&gt;&lt;pre class=&quot;sourceCode r&quot;&gt;&lt;code class=&quot;sourceCode r&quot;&gt;&lt;span id=&quot;cb15-1&quot;&gt;&lt;a href=&quot;#cb15-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;fu&quot;&gt;reduce&lt;/span&gt;(covered_granges, &lt;span class=&quot;at&quot;&gt;min.gapwidth=&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;31&lt;/span&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;pre&gt;&lt;code&gt;## GRanges object with 1379 ranges and 0 metadata columns:
##                seqnames        ranges strand
##                   &amp;lt;Rle&amp;gt;     &amp;lt;IRanges&amp;gt;  &amp;lt;Rle&amp;gt;
##      [1]   NC_000001.11   10041-10101      *
##      [2]   NC_000001.11 118531-118688      *
##      [3]   NC_000001.11 295097-295254      *
##      [4]   NC_000001.11 377069-377226      *
##      [5]   NC_000001.11 709516-709673      *
##      ...            ...           ...    ...
##   [1375]    NT_187617.1   59572-59732      *
##   [1376] NW_003315930.1   14229-14368      *
##   [1377] NW_003315952.3   57671-57785      *
##   [1378] NW_003315959.1 134807-134820      *
##   [1379] NW_003571050.1 380055-380202      *
##   -------
##   seqinfo: 299 sequences from an unspecified genome; no seqlengths&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As you can see, this reduced the number of ranges from 1401 to
1379.&lt;/p&gt;
</description>
                        <pubDate>Wed, 11 Jul 2018 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2018-07-11-chip-seq-consensus</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2018-07-11-chip-seq-consensus.html</guid>
                </item>
        
                <item>
                        <title>Sometimes all you need is to cut adapters</title>
                        <description>&lt;p&gt;When you see a FastQC box like this, you know that something is
wrong.&lt;/p&gt;
&lt;figure&gt;
&lt;img src=&quot;/img/adapters/fastqc1.png&quot; alt=&quot;FastQC summary box&quot; /&gt;
&lt;figcaption aria-hidden=&quot;true&quot;&gt;FastQC summary box&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;But what exactly?&lt;/p&gt;
&lt;p&gt;Overrepresented sequences may indicate adapters (although,
ironically, the Adapter Content is one of the few green check marks
here), and duplicated sequences could be removed, but what do you do
about the GC levels, per base sequence content, and per tile quality
bias?&lt;/p&gt;
&lt;p&gt;Here’s the table of overrepresented sequences identified by
FastQC:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;
Sequence
&lt;/th&gt;
&lt;th&gt;
Count
&lt;/th&gt;
&lt;th&gt;
Percentage
&lt;/th&gt;
&lt;th&gt;
Possible Source
&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
GATCGGAAGAGCACACGTCTGAACTCCAGTCACTCTCGCGCATCTCGTAT
&lt;/td&gt;
&lt;td&gt;
17953666
&lt;/td&gt;
&lt;td&gt;
21.724791264966143
&lt;/td&gt;
&lt;td&gt;
TruSeq Adapter, Index 8 (97% over 36bp)
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
ATCGGAAGAGCACACGTCTGAACTCCAGTCACTCTCGCGCATCTCGTATG
&lt;/td&gt;
&lt;td&gt;
3032064
&lt;/td&gt;
&lt;td&gt;
3.6689419031198587
&lt;/td&gt;
&lt;td&gt;
TruSeq Adapter, Index 8 (97% over 35bp)
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
GTTCGGAAGAGCACACGTCTGAACTCCAGTCACTCTCGCGCATCTCGTAT
&lt;/td&gt;
&lt;td&gt;
161627
&lt;/td&gt;
&lt;td&gt;
0.19557637074136738
&lt;/td&gt;
&lt;td&gt;
TruSeq Adapter, Index 3 (97% over 34bp)
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
AATCGGAAGAGCACACGTCTGAACTCCAGTCACTCTCGCGCATCTCGTAT
&lt;/td&gt;
&lt;td&gt;
117432
&lt;/td&gt;
&lt;td&gt;
0.14209831506431633
&lt;/td&gt;
&lt;td&gt;
TruSeq Adapter, Index 3 (97% over 34bp)
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
ATCGGAAGAGCACACGTCTGAACTCCCGTCACTCTCGCGCATCTCGTATG
&lt;/td&gt;
&lt;td&gt;
98036
&lt;/td&gt;
&lt;td&gt;
0.11862823093914193
&lt;/td&gt;
&lt;td&gt;
TruSeq Adapter, Index 3 (96% over 33bp)
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
GATAGGAAGAGCACACGTCTGAACTCCAGTCACTCTCGCGCATCTCGTAT
&lt;/td&gt;
&lt;td&gt;
82961
&lt;/td&gt;
&lt;td&gt;
0.10038676268862615
&lt;/td&gt;
&lt;td&gt;
TruSeq Adapter, Index 3 (97% over 34bp)
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Examining the reads further clarifies the picture: it’s not just that
25% of reads contain adapter sequences; most of them &lt;em&gt;are&lt;/em&gt;
adapter sequences right from base 1.&lt;/p&gt;
&lt;p&gt;This can already explain a lot of what we’re seeing. If a quarter of
the reads are variations of the same fixed string, it will definitely
skew the GC content and the per base sequence content distributions.
This also explains the tile bias — there was some issue with the library
that was localized to a couple of lanes.&lt;/p&gt;
&lt;p&gt;But the most miraculous thing is how trimming/removal of these
adapter sequences affects the quality score distribution. Even if part
of the reads were sequenced from adapter DNA instead of endogenous DNA,
you wouldn’t necessarily expect those reads to be of lower quality,
would you?&lt;/p&gt;
&lt;p&gt;Here’s the per-base sequence quality in the raw data:&lt;/p&gt;
&lt;figure&gt;
&lt;img src=&quot;/img/adapters/fastqc2.png&quot;
alt=&quot;FastQC per-base sequence quality before adapter removal&quot; /&gt;
&lt;figcaption aria-hidden=&quot;true&quot;&gt;FastQC per-base sequence quality before
adapter removal&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;The analysis that I’m doing (ChIP-seq peak calling) is not very
sensitive to the read length, so I was thinking about trimming the reads
to 75bp or so just to avoid those questionable bases at the end.&lt;/p&gt;
&lt;p&gt;But look what happens if I simply remove the adapters, without doing
any other trimming or quality filtering:&lt;/p&gt;
&lt;figure&gt;
&lt;img src=&quot;/img/adapters/fastqc3.png&quot;
alt=&quot;FastQC per-base sequence quality after adapter removal&quot; /&gt;
&lt;figcaption aria-hidden=&quot;true&quot;&gt;FastQC per-base sequence quality after
adapter removal&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;I don’t quite understand why this happens, but a couple of
explanations come to mind:&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;&lt;p&gt;There’s a stretch of &lt;code&gt;A&lt;/code&gt;s in the second half of the
adapter sequence; e.g.&lt;/p&gt;
&lt;div style=&quot;font-size:11pt;&quot;&gt;
&lt;pre&gt;&lt;code&gt;GATCGGAAGAGCACACGTCTGAACTCCAGTCACTCTCGCGCATCTCGTATGCCGTCTTCTGCTTGAAAAAAAAAAAAAAACACGAACATGCCGGTTGAAGCAAGTCTCCTGTATCTGGCCTCCACC
                                                                 ^^^^^^^^^^^^^^^&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;So it could be this poly(A) segment &lt;a
href=&quot;https://omicsomics.blogspot.com/2012/01/does-illlmina-also-have-homopolymer.html&quot;&gt;that
leads to errors&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;There could also be a common issue that caused both adapter-only
fragments and low quality scores, although I don’t have any ideas about
what it could be.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;In any case, simply trimming the adapter sequence and removing all
reads shorter than 40bp fixed pretty much everything:&lt;/p&gt;
&lt;figure&gt;
&lt;img src=&quot;/img/adapters/fastqc4.png&quot;
alt=&quot;FastQC summary box after removing adapter sequences&quot; /&gt;
&lt;figcaption aria-hidden=&quot;true&quot;&gt;FastQC summary box after removing adapter
sequences&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;The only remaining warning simply &lt;a
href=&quot;https://www.bioinformatics.babraham.ac.uk/projects/fastqc/Help/3%20Analysis%20Modules/7%20Sequence%20Length%20Distribution.html&quot;&gt;tells
us&lt;/a&gt; that not all sequences are of the same length, as we would expect
after trimming adapters:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;This module will raise a warning if all sequences are not the same
length.&lt;/p&gt;
&lt;p&gt;[…]&lt;/p&gt;
&lt;p&gt;For some sequencing platforms it is entirely normal to have different
read lengths so warnings here can be ignored.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;For the record, the command I used was&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cutadapt --cores={threads} -a GATCGGAAGAGCACACGTCTGAACTCCAGTCAC -o {output} {input} --overlap 4 --minimum-length 40&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You can also browse and compare the full FastQC reports &lt;a
href=&quot;/files/2018-06-19-cutting-adapters/fastqc-before.html&quot;&gt;before&lt;/a&gt;
and &lt;a
href=&quot;/files/2018-06-19-cutting-adapters/fastqc-after.html&quot;&gt;after&lt;/a&gt;
adapter trimming.&lt;/p&gt;
</description>
                        <pubDate>Tue, 19 Jun 2018 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2018-06-19-cutting-adapters</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2018-06-19-cutting-adapters.html</guid>
                </item>
        
                <item>
                        <title>Encrypted reminders with Nudgemail</title>
                        <description>&lt;p&gt;I use Trello as my main GTD tool, and it works great for the
short-term stuff. Sometimes, however, I have a task that I won’t be able
to do until 4 months later. While I could create a Trello card and set
its due date to October 20th, I will keep seeing it every time I review
my trello board. Each time I’ll be reminded of this relatively
unpleasant task, adding up to a significant mental cost.&lt;/p&gt;
&lt;p&gt;The perfect solution to this problem is provided by &lt;a
href=&quot;https://www.nudgemail.com/&quot;&gt;Nudgemail&lt;/a&gt;. Here’s how it works:
you send an email to &lt;code&gt;nudge@nudgemail.com&lt;/code&gt;, put the desired
time and/or date in the subject field (e.g. “October 20”), and on that
date it sends you the email back.&lt;/p&gt;
&lt;figure&gt;
&lt;img src=&quot;/img/nudgemail1.png&quot; alt=&quot;Example email to Nudgemail&quot; /&gt;
&lt;figcaption aria-hidden=&quot;true&quot;&gt;Example email to Nudgemail&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;That has a few problems of its own, however:&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;&lt;p&gt;There is something creepy about sending an email containing
personal information to a random email address. Will they sell it to
advertizers?&lt;/p&gt;
&lt;p&gt;To be fair, their &lt;a
href=&quot;https://www.nudgemail.com/privacy/&quot;&gt;privacy policy&lt;/a&gt; looks very
noble:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Nudgemail does not create profiles for our users, public or private.
We will not share your email address or any other information
transmitted through the System with anyone outside of your personally
designated recipients. […] No member of the Nudgemail team or third
party, aside from your designated recipients, will have direct access to
emails or attachments sent to the Service.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Still feels creepy though.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;When I get my email back, I might not even remember the fact that
I wrote it. How do I know it was really me, and not someone giving me
instructions by pretending to be me from the past?&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Easy: sign and encrypt the email with GPG. Here are a few tips:&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;&lt;p&gt;Send an empty email to &lt;code&gt;plain@nudgemail.com&lt;/code&gt;; this
will instruct Nudgemail to send you plain-text email instead of HTML
ones, which will make it easier to extract the PGP text.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Nudgemail does not support attachments; so use inline PGP instead
of PGP/MIME.&lt;/p&gt;
&lt;p&gt;If you use Enigmail, it allows you to declare per-recipient rules,
where you can instruct it to use your PGP key, force signing and
encryption, and disable PGP/MIME as shown below.&lt;/p&gt;
&lt;figure&gt;
&lt;img src=&quot;/img/nudgemail2.png&quot;
alt=&quot;Per-recipient rules for Nudgemail in Enigmail&quot; /&gt;
&lt;figcaption aria-hidden=&quot;true&quot;&gt;Per-recipient rules for Nudgemail in
Enigmail&lt;/figcaption&gt;
&lt;/figure&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;For PGP/MIME to work better, make sure your outgoing emails are
plain text. (Thunderbird itself has per-recipient rules where you can
configure this.)&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Here’s how the result looks:&lt;/p&gt;
&lt;figure&gt;
&lt;img src=&quot;/img/nudgemail3.png&quot; alt=&quot;Example email from Nudgemail&quot; /&gt;
&lt;figcaption aria-hidden=&quot;true&quot;&gt;Example email from Nudgemail&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Unfortunately Nudgemail messes with the email’s contents a bit, and
it can no longer be automatically decoded, but you can easily copy-paste
the PGP part and decrypt it:&lt;/p&gt;
&lt;figure&gt;
&lt;img src=&quot;/img/nudgemail4.png&quot; alt=&quot;Decrypted email from Nudgemail&quot; /&gt;
&lt;figcaption aria-hidden=&quot;true&quot;&gt;Decrypted email from
Nudgemail&lt;/figcaption&gt;
&lt;/figure&gt;
</description>
                        <pubDate>Fri, 15 Jun 2018 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2018-06-15-encrypted-reminders-nudgemail</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2018-06-15-encrypted-reminders-nudgemail.html</guid>
                </item>
        
                <item>
                        <title>QuickCheck vs. SmallCheck</title>
                        <description>&lt;p&gt;QuickCheck and SmallCheck are the two classical libraries for
property testing in Haskell. There are newer developments, like &lt;a
href=&quot;https://github.com/leepike/SmartCheck&quot;&gt;SmartCheck&lt;/a&gt; and &lt;a
href=&quot;https://github.com/hedgehogqa/haskell-hedgehog&quot;&gt;Hedgehog&lt;/a&gt;, but
I haven’t tried them much yet.&lt;/p&gt;
&lt;p&gt;So here is my take on the comparative strengths and weaknesses of the
current versions of QuickCheck and SmallCheck (2.11.3 and 1.1.4,
respectively). Being the maintainer of SmallCheck, I am obviously
somewhat biased towards it. But quite often I would prefer QuickCheck to
SmallCheck for a specific task. It also sometimes happens that I think
QuickCheck would work better in principle for a given task, but in
practice SmallCheck is more convenient for that task — usually it has to
do with generic instances or failure reporting. So here are the
considerations I take into account when choosing between the two.&lt;/p&gt;
&lt;p&gt;If you do not know much about QuickCheck and/or SmallCheck, the main
difference between them is that QuickCheck generates random test cases,
whereas SmallCheck enumerates test cases exhaustively up to some depth.
Some (though not all) of the pros and cons come from this fundamental
difference in paradigms.&lt;/p&gt;
&lt;h2 id=&quot;advantages-of-quickcheck&quot;&gt;Advantages of QuickCheck&lt;/h2&gt;
&lt;h3 id=&quot;control-over-the-number-of-testsexecution-time&quot;&gt;Control over the
number of tests/execution time&lt;/h3&gt;
&lt;p&gt;With SmallCheck, the number of tests is usually exponential in their
depth. Say, when enumerating trees (from &lt;code&gt;Data.Tree&lt;/code&gt;), depth
5 gives you 189 tests in less then 0.01s, while depth 6 gives 6479 tests
in 4s. If you only have the patience to run 1000 tests, you have to
settle for 189. QuickCheck, on the other hand, allows you to set the
exact number of tests independently from their depth (which is called
&lt;em&gt;size&lt;/em&gt; in QuickCheck).&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Update (2018-07-05)&lt;/em&gt;. In smallcheck-1.1.5, I added a
function&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb1&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb1-1&quot;&gt;&lt;a href=&quot;#cb1-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;limit ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Monad&lt;/span&gt; m &lt;span class=&quot;ot&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Int&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Series&lt;/span&gt; m a &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Series&lt;/span&gt; m a&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;which acts similarly to &lt;code&gt;take&lt;/code&gt; for lists. It is still not
as convenient as QuickCheck, because you have to apply it to each “big”
generator as opposed to setting a single global limit on the number of
tests, but you can use it to fight the exponential blowup.&lt;/p&gt;
&lt;h3 id=&quot;floating-point-numbers&quot;&gt;Floating-point numbers&lt;/h3&gt;
&lt;p&gt;SmallCheck has instances for floating-point numbers, e.g.&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb2&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb2-1&quot;&gt;&lt;a href=&quot;#cb2-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;op&quot;&gt;&amp;gt;&lt;/span&gt; listSeries &lt;span class=&quot;dv&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;ot&quot;&gt; ::&lt;/span&gt; [&lt;span class=&quot;dt&quot;&gt;Positive&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Float&lt;/span&gt;]&lt;/span&gt;
&lt;span id=&quot;cb2-2&quot;&gt;&lt;a href=&quot;#cb2-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;[&lt;span class=&quot;fl&quot;&gt;1.0&lt;/span&gt;,&lt;span class=&quot;fl&quot;&gt;2.0&lt;/span&gt;,&lt;span class=&quot;fl&quot;&gt;0.5&lt;/span&gt;,&lt;span class=&quot;fl&quot;&gt;4.0&lt;/span&gt;,&lt;span class=&quot;fl&quot;&gt;0.25&lt;/span&gt;,&lt;span class=&quot;fl&quot;&gt;8.0&lt;/span&gt;,&lt;span class=&quot;fl&quot;&gt;0.125&lt;/span&gt;,&lt;span class=&quot;fl&quot;&gt;16.0&lt;/span&gt;,&lt;span class=&quot;fl&quot;&gt;3.0&lt;/span&gt;,&lt;span class=&quot;fl&quot;&gt;6.25e-2&lt;/span&gt;,&lt;span class=&quot;fl&quot;&gt;6.0&lt;/span&gt;,&lt;span class=&quot;fl&quot;&gt;1.5&lt;/span&gt;,&lt;span class=&quot;fl&quot;&gt;12.0&lt;/span&gt;,&lt;span class=&quot;fl&quot;&gt;0.75&lt;/span&gt;,&lt;span class=&quot;fl&quot;&gt;24.0&lt;/span&gt;,&lt;span class=&quot;fl&quot;&gt;0.375&lt;/span&gt;,&lt;span class=&quot;fl&quot;&gt;48.0&lt;/span&gt;,&lt;span class=&quot;fl&quot;&gt;0.1875&lt;/span&gt;]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;These are probably enough if you need to fill some fractional field
in a data type, but the logic of your functions doesn’t depend on the
number in a complex way.&lt;/p&gt;
&lt;p&gt;But if you are testing any truly numerical code (say, matrix
operations or physics simulation), it is much more useful to have
QuickCheck generate random floating-point numbers.&lt;/p&gt;
&lt;h2 id=&quot;advantages-of-smallcheck&quot;&gt;Advantages of SmallCheck&lt;/h2&gt;
&lt;h3 id=&quot;generic-deriving&quot;&gt;Generic deriving&lt;/h3&gt;
&lt;p&gt;If you have a couple of types that rarely change, writing the
instances by hand may not a big deal.&lt;/p&gt;
&lt;p&gt;Often, especially when writing tests for commercial code, there is a
big number of nested algebraic data types. And even if you have the
patience to write the instances, they will become incomplete the next
time a constructor is added to one of the types (and the compiler won’t
warn you).&lt;/p&gt;
&lt;p&gt;So it is essential to be able to derive most of the instances.
SmallCheck has had generic instances since 2011, thanks to the
contribution from Bas van Dijk. QuickCheck still does not have them (&lt;a
href=&quot;https://github.com/nick8325/quickcheck/issues/137&quot;&gt;github
issue&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;There is a separate package, generic-arbitrary, but it doesn’t seem
to support recursive data types. The recursive types also seem to be the
reason why QuickCheck itself doesn’t have the generic
implementation.&lt;/p&gt;
&lt;p&gt;The solution to the recursive type problem is straightforward: reduce
the depth (size) every time you descend into a nested type. As an
example, here’s an instance for trees from &lt;code&gt;Data.Tree&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb3&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb3-1&quot;&gt;&lt;a href=&quot;#cb3-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;instance&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Arbitrary&lt;/span&gt; a &lt;span class=&quot;ot&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Arbitrary&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;Tree&lt;/span&gt; a) &lt;span class=&quot;kw&quot;&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-2&quot;&gt;&lt;a href=&quot;#cb3-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  arbitrary &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; scale (\n &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;max&lt;/span&gt; (n&lt;span class=&quot;op&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;) &lt;span class=&quot;dv&quot;&gt;0&lt;/span&gt;) &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-3&quot;&gt;&lt;a href=&quot;#cb3-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;dt&quot;&gt;Node&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;&amp;lt;$&amp;gt;&lt;/span&gt; arbitrary &lt;span class=&quot;op&quot;&gt;&amp;lt;*&amp;gt;&lt;/span&gt; arbitrary&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This approach is not ideal (your size may get down to 0 too quickly),
but IMO it is better than no generic instances at all.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Update (2018-07-05)&lt;/em&gt;. There are some third-party packages
that implement generic deriving for QuickCheck &lt;em&gt;and&lt;/em&gt; support
recursive types, in particular &lt;a
href=&quot;https://hackage.haskell.org/package/testing-feat&quot;&gt;testing-feat&lt;/a&gt;
and &lt;a
href=&quot;https://hackage.haskell.org/package/generic-random&quot;&gt;generic-random&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;testing-feat&lt;/strong&gt; looks very cool and powerful from a
theoretical perspective, and I’d like to study it in depth some day. In
practice it involves definitions like&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb4&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb4-1&quot;&gt;&lt;a href=&quot;#cb4-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;deriveEnumerable &amp;#39;&lt;span class=&quot;dt&quot;&gt;&amp;#39;MyType&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-2&quot;&gt;&lt;a href=&quot;#cb4-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;instance&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Arbitrary&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;MyType&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-3&quot;&gt;&lt;a href=&quot;#cb4-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-4&quot;&gt;&lt;a href=&quot;#cb4-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    arbitrary &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; sized uniform&lt;/span&gt;
&lt;span id=&quot;cb4-5&quot;&gt;&lt;a href=&quot;#cb4-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    shrink &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; genericShrink&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Sometimes you need to define an &lt;code&gt;Enumerable&lt;/code&gt; instance for
an abstract or primitive type, which I ended up doing like this (for
&lt;code&gt;Text&lt;/code&gt;):&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb5&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb5-1&quot;&gt;&lt;a href=&quot;#cb5-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;instance&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Enumerable&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;T.Text&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-2&quot;&gt;&lt;a href=&quot;#cb5-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  enumerate &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; share (c1 T.pack)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;generic-random&lt;/strong&gt; is a bit easier to use, since there’s
no additional &lt;code&gt;Enumerable&lt;/code&gt; class. The declaration looks like
this:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb6&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb6-1&quot;&gt;&lt;a href=&quot;#cb6-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;instance&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Arbitrary&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;MyType&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-2&quot;&gt;&lt;a href=&quot;#cb6-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-3&quot;&gt;&lt;a href=&quot;#cb6-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    arbitrary &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; genericArbitraryU&amp;#39;&lt;/span&gt;
&lt;span id=&quot;cb6-4&quot;&gt;&lt;a href=&quot;#cb6-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    shrink &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; genericShrink&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;In both cases, &lt;code&gt;genericShrink&lt;/code&gt; comes from the QuickCheck
package itself, but it’s not the default implementation for
&lt;code&gt;shrink&lt;/code&gt;; the default is &lt;code&gt;shrink _ = []&lt;/code&gt;.&lt;/p&gt;
&lt;h3 id=&quot;failure-reporting&quot;&gt;Failure reporting&lt;/h3&gt;
&lt;p&gt;Say we have a property&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb7&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb7-1&quot;&gt;&lt;a href=&quot;#cb7-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;prop x &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;reverse&lt;/span&gt; (&lt;span class=&quot;fu&quot;&gt;reverse&lt;/span&gt; x) &lt;span class=&quot;op&quot;&gt;==&lt;/span&gt; x&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;By default, both SmallCheck and QuickCheck only tell you the
generated values that led to the failure (i.e. &lt;code&gt;x&lt;/code&gt;). But I
would also like to know &lt;em&gt;why&lt;/em&gt; the test failed — in this case,
what &lt;code&gt;reverse (reverse x)&lt;/code&gt; was.&lt;/p&gt;
&lt;p&gt;There is a &lt;a
href=&quot;https://stackoverflow.com/q/4772902/110081&quot;&gt;StackOverflow
question&lt;/a&gt; about this with two answers, neither of which is
perfect.&lt;/p&gt;
&lt;p&gt;Edward Z. Yang says:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Because QuickCheck gives you the inputs to the function, and because
the code under test is pure (it is, right?), you can just feed those
inputs to the function and get the result. This is more flexible,
because with those inputs you can also repeatedly test with tweaks to
the original function until it’s correct.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;There are many reasons why this may not work:&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;The code may not be pure by design — both SmallCheck and QuickCheck
are capable of testing IO code.&lt;/li&gt;
&lt;li&gt;The code may be intended to be pure, but the very &lt;a
href=&quot;https://github.com/amosr/limp-cbc/issues/5&quot;&gt;bug you are trying to
fix&lt;/a&gt; may lead to it being impure/non-deterministic.&lt;/li&gt;
&lt;li&gt;Copy-pasting values may not be very convenient: think large
matrices.&lt;/li&gt;
&lt;li&gt;Also, strings produced by &lt;code&gt;Show&lt;/code&gt; do not always map back
to the original values effortlessly. E.g. Maps, Sets, and Vectors all
result in &lt;code&gt;fromList [...]&lt;/code&gt; when shown. If you have several of
them in the same structure, you’ll have to disambiguate those
&lt;code&gt;fromList&lt;/code&gt;s.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The other answer, by Paul Johnson, gives a working solution (using
&lt;code&gt;MkResult&lt;/code&gt;), but it is rather unwieldy, and you have to
include the parameter values manually if you need them.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Update (2018-07-05)&lt;/em&gt;. I’ve since found and &lt;a
href=&quot;https://stackoverflow.com/a/50588581/110081&quot;&gt;posted&lt;/a&gt; a much
better way to report a failure in QuickCheck:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb8&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb8-1&quot;&gt;&lt;a href=&quot;#cb8-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Test.QuickCheck.Property&lt;/span&gt; (succeeded, failed, reason)&lt;/span&gt;
&lt;span id=&quot;cb8-2&quot;&gt;&lt;a href=&quot;#cb8-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb8-3&quot;&gt;&lt;a href=&quot;#cb8-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;prop a b &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb8-4&quot;&gt;&lt;a href=&quot;#cb8-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;if&lt;/span&gt; res &lt;span class=&quot;op&quot;&gt;/=&lt;/span&gt; []&lt;/span&gt;
&lt;span id=&quot;cb8-5&quot;&gt;&lt;a href=&quot;#cb8-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;kw&quot;&gt;then&lt;/span&gt; succeeded&lt;/span&gt;
&lt;span id=&quot;cb8-6&quot;&gt;&lt;a href=&quot;#cb8-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;kw&quot;&gt;else&lt;/span&gt; failed { reason &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; reason }&lt;/span&gt;
&lt;span id=&quot;cb8-7&quot;&gt;&lt;a href=&quot;#cb8-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;   &lt;span class=&quot;kw&quot;&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb8-8&quot;&gt;&lt;a href=&quot;#cb8-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      (res, reason) &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; checkCode a b&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;In SmallCheck, you can return &lt;code&gt;Either String String&lt;/code&gt;
instead of &lt;code&gt;Bool&lt;/code&gt;, where the &lt;code&gt;String&lt;/code&gt;s give
explanation for failure and success, respectively. For example, this
property&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb9&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb9-1&quot;&gt;&lt;a href=&quot;#cb9-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;prop_reverse ::&lt;/span&gt; [&lt;span class=&quot;dt&quot;&gt;Int&lt;/span&gt;] &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Bool&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb9-2&quot;&gt;&lt;a href=&quot;#cb9-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;prop_reverse x &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;reverse&lt;/span&gt; x &lt;span class=&quot;op&quot;&gt;==&lt;/span&gt; x&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;results in the message&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;there exists [0,1] such that
  condition is false&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;But we can change the property to explain itself&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb11&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb11-1&quot;&gt;&lt;a href=&quot;#cb11-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;prop_reverse ::&lt;/span&gt; [&lt;span class=&quot;dt&quot;&gt;Int&lt;/span&gt;] &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Either&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;String&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb11-2&quot;&gt;&lt;a href=&quot;#cb11-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;prop_reverse x &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb11-3&quot;&gt;&lt;a href=&quot;#cb11-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;reverse&lt;/span&gt; x &lt;span class=&quot;op&quot;&gt;==&lt;/span&gt; x&lt;/span&gt;
&lt;span id=&quot;cb11-4&quot;&gt;&lt;a href=&quot;#cb11-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;kw&quot;&gt;then&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Right&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;quot;Match&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb11-5&quot;&gt;&lt;a href=&quot;#cb11-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;kw&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Left&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;quot;reverse x == &amp;quot;&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;++&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;show&lt;/span&gt; (&lt;span class=&quot;fu&quot;&gt;reverse&lt;/span&gt; x)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;which results in&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;there exists [0,1] such that
  reverse x = [1,0]&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;better-than-shrinking&quot;&gt;Better than shrinking&lt;/h3&gt;
&lt;p&gt;QuickCheck tends to produce complex counterexamples and then tries to
shrink them to find simpler ones. While shrinking does lead to somewhat
simpler examples, they are usually not minimal. Also, it’s on you to
implement the shrinking function for your own types (although there is
&lt;code&gt;genericShrink&lt;/code&gt;).&lt;/p&gt;
&lt;p&gt;Because SmallCheck enumerates the values in order, from smaller to
bigger, it automatically produces the minimal example.&lt;/p&gt;
&lt;h3 id=&quot;determinism-and-exhaustiveness&quot;&gt;Determinism and
exhaustiveness&lt;/h3&gt;
&lt;p&gt;Because QuickCheck generates its examples randomly, the set of test
cases your property is tested on is rather arbitrary. (It also changes
from run to run by default, though this can be fixed by suppplying a
fixed seed.)&lt;/p&gt;
&lt;p&gt;Sometimes that’s good: if you have a high- or infinite-dimensional
space of possibilities, all you can hope for is to test on a few diverse
samples from that space. But other times, that space is narrow, and it’s
better to test deterministically and exhaustively.&lt;/p&gt;
</description>
                        <pubDate>Fri, 25 May 2018 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2018-05-25-quickcheck-vs-smallcheck</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2018-05-25-quickcheck-vs-smallcheck.html</guid>
                </item>
        
                <item>
                        <title>Disable Sony What&apos;s New notifications</title>
                        <description>&lt;p&gt;If you have a Sony smartphone, you noticed the annoying notifications
from Sony’s built-in WhatsNew app. They look like this:&lt;/p&gt;
&lt;figure&gt;
&lt;img src=&quot;/img/sony-whatsnew-1.jpeg&quot; class=&quot;screenshot&quot; /&gt; &lt;img
src=&quot;/img/sony-whatsnew-2.jpeg&quot; class=&quot;screenshot&quot; /&gt;
&lt;/figure&gt;
&lt;p&gt;Sony also made it impossible to disable the app or block the
notifications through the usual means. Where normally you’d see an
option to block all of the app’s notifications or disable the app
itself, there are no such options for WhatsNew.&lt;/p&gt;
&lt;figure&gt;
&lt;img src=&quot;/img/sony-whatsnew-3.jpeg&quot; class=&quot;screenshot&quot; /&gt; &lt;img
src=&quot;/img/sony-whatsnew-4.jpeg&quot; class=&quot;screenshot&quot; /&gt; &lt;img
src=&quot;/img/sony-whatsnew-5.jpeg&quot; class=&quot;screenshot&quot; /&gt;
&lt;/figure&gt;
&lt;p&gt;So for a long time I assumed that it was impossible to get rid of
these notifications, short of rooting the phone.&lt;/p&gt;
&lt;p&gt;Then one day I watched The Shawshank Redemption and was inspired by
the scene where Andy was writing letters to senators. Maybe if I write a
lot of letters to Sony’s support, they will do something about it?&lt;/p&gt;
&lt;figure&gt;
&lt;img src=&quot;/img/sony-whatsnew-shawshank.jpeg&quot;
alt=&quot;So Andy started writing a letter a week…&quot; /&gt;
&lt;figcaption aria-hidden=&quot;true&quot;&gt;So Andy started writing a letter a
week…&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;To my surprise, I got a response right away.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Dear Roman,&lt;/p&gt;
&lt;p&gt;Thank you for contacting the Sony Xperia support centre.&lt;/p&gt;
&lt;p&gt;In regards of your query on how to disable the WhatsNew notifications
on your Sony Xperia Device.&lt;/p&gt;
&lt;p&gt;Kindly follow the below steps.&lt;/p&gt;
&lt;p&gt;You can avoid getting notifications from the What’s New app by
turning off Show notifications in the app. To disable notifications in
What’s New&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;From your Home screen, tap the Application screen icon.&lt;/li&gt;
&lt;li&gt;Find and tap What’s New.&lt;/li&gt;
&lt;li&gt;Drag the left edge of the screen to the right, then find and tap
Settings.&lt;/li&gt;
&lt;li&gt;Drag the slider beside Show notifications to the left.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Note! The notifications of the application updates are exempted from
the above setting. These updates may contain critical security and
functionality patches that make your device more secure since it
protects all the personal data on your device, and also improves the
performance.&lt;/p&gt;
&lt;p&gt;We hope this helps.&lt;/p&gt;
&lt;p&gt;Kind Regards,&lt;br /&gt;
Mike [redacted]&lt;br /&gt;
Sony Xperia UK Customer Services&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;And indeed, the setting was there:&lt;/p&gt;
&lt;figure&gt;
&lt;img src=&quot;/img/sony-whatsnew-6.jpeg&quot; class=&quot;screenshot2&quot; /&gt;
&lt;/figure&gt;
&lt;p&gt;Thanks, Mike!&lt;/p&gt;
&lt;p&gt;The only caveat (and the reason I hadn’t looked in the settings
before) is that in order to get to the settings, you need to accept the
app’s terms and conditions.&lt;/p&gt;
</description>
                        <pubDate>Mon, 14 May 2018 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2018-05-14-disable-sony-whatsnew-notifications</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2018-05-14-disable-sony-whatsnew-notifications.html</guid>
                </item>
        
                <item>
                        <title>What is this weird math letter?</title>
                        <description>&lt;p&gt;Occasionally I would read a mathematics paper or book and see a
strange calligraphic symbol that I have no idea how to pronounce.&lt;/p&gt;
&lt;p&gt;Like here:&lt;/p&gt;
&lt;figure&gt;
&lt;img src=&quot;/img/mathscr1.png&quot; /&gt;
&lt;/figure&gt;
&lt;p&gt;Or here:&lt;/p&gt;
&lt;figure&gt;
&lt;img src=&quot;/img/mathscr2.png&quot; /&gt;
&lt;/figure&gt;
&lt;p&gt;This is a problem because I, as most other people, &lt;a
href=&quot;https://en.wikipedia.org/wiki/Subvocalization&quot;&gt;struggle to read
what I can’t pronounce&lt;/a&gt; even when not reading aloud.&lt;/p&gt;
&lt;p&gt;When you encounter a symbol like this (which belongs to a family of
typefaces called &lt;a
href=&quot;https://en.wikipedia.org/wiki/Script_typeface#Formal_scripts&quot;&gt;formal
scripts&lt;/a&gt;), just look it up in the table below, and you’ll know what
letter it stands for.&lt;/p&gt;
&lt;table&gt;
&lt;caption&gt;
The table of formal script (“mathscr”) letters.
&lt;/caption&gt;
&lt;tr&gt;
&lt;td&gt;
A
&lt;/td&gt;
&lt;td&gt;
&lt;span class=&quot;math inline&quot;&gt;\(\mathscr{A}\)&lt;/span&gt;
&lt;/td&gt;
&lt;td&gt;
N
&lt;/td&gt;
&lt;td&gt;
&lt;span class=&quot;math inline&quot;&gt;\(\mathscr{N}\)&lt;/span&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
B
&lt;/td&gt;
&lt;td&gt;
&lt;span class=&quot;math inline&quot;&gt;\(\mathscr{B}\)&lt;/span&gt;
&lt;/td&gt;
&lt;td&gt;
O
&lt;/td&gt;
&lt;td&gt;
&lt;span class=&quot;math inline&quot;&gt;\(\mathscr{O}\)&lt;/span&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
C
&lt;/td&gt;
&lt;td&gt;
&lt;span class=&quot;math inline&quot;&gt;\(\mathscr{C}\)&lt;/span&gt;
&lt;/td&gt;
&lt;td&gt;
P
&lt;/td&gt;
&lt;td&gt;
&lt;span class=&quot;math inline&quot;&gt;\(\mathscr{P}\)&lt;/span&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
D
&lt;/td&gt;
&lt;td&gt;
&lt;span class=&quot;math inline&quot;&gt;\(\mathscr{D}\)&lt;/span&gt;
&lt;/td&gt;
&lt;td&gt;
Q
&lt;/td&gt;
&lt;td&gt;
&lt;span class=&quot;math inline&quot;&gt;\(\mathscr{Q}\)&lt;/span&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
E
&lt;/td&gt;
&lt;td&gt;
&lt;span class=&quot;math inline&quot;&gt;\(\mathscr{E}\)&lt;/span&gt;
&lt;/td&gt;
&lt;td&gt;
R
&lt;/td&gt;
&lt;td&gt;
&lt;span class=&quot;math inline&quot;&gt;\(\mathscr{R}\)&lt;/span&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
F
&lt;/td&gt;
&lt;td&gt;
&lt;span class=&quot;math inline&quot;&gt;\(\mathscr{F}\)&lt;/span&gt;
&lt;/td&gt;
&lt;td&gt;
S
&lt;/td&gt;
&lt;td&gt;
&lt;span class=&quot;math inline&quot;&gt;\(\mathscr{S}\)&lt;/span&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
G
&lt;/td&gt;
&lt;td&gt;
&lt;span class=&quot;math inline&quot;&gt;\(\mathscr{G}\)&lt;/span&gt;
&lt;/td&gt;
&lt;td&gt;
T
&lt;/td&gt;
&lt;td&gt;
&lt;span class=&quot;math inline&quot;&gt;\(\mathscr{T}\)&lt;/span&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
H
&lt;/td&gt;
&lt;td&gt;
&lt;span class=&quot;math inline&quot;&gt;\(\mathscr{H}\)&lt;/span&gt;
&lt;/td&gt;
&lt;td&gt;
U
&lt;/td&gt;
&lt;td&gt;
&lt;span class=&quot;math inline&quot;&gt;\(\mathscr{U}\)&lt;/span&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
I
&lt;/td&gt;
&lt;td&gt;
&lt;span class=&quot;math inline&quot;&gt;\(\mathscr{I}\)&lt;/span&gt;
&lt;/td&gt;
&lt;td&gt;
V
&lt;/td&gt;
&lt;td&gt;
&lt;span class=&quot;math inline&quot;&gt;\(\mathscr{V}\)&lt;/span&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
J
&lt;/td&gt;
&lt;td&gt;
&lt;span class=&quot;math inline&quot;&gt;\(\mathscr{J}\)&lt;/span&gt;
&lt;/td&gt;
&lt;td&gt;
W
&lt;/td&gt;
&lt;td&gt;
&lt;span class=&quot;math inline&quot;&gt;\(\mathscr{W}\)&lt;/span&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
K
&lt;/td&gt;
&lt;td&gt;
&lt;span class=&quot;math inline&quot;&gt;\(\mathscr{K}\)&lt;/span&gt;
&lt;/td&gt;
&lt;td&gt;
X
&lt;/td&gt;
&lt;td&gt;
&lt;span class=&quot;math inline&quot;&gt;\(\mathscr{X}\)&lt;/span&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
L
&lt;/td&gt;
&lt;td&gt;
&lt;span class=&quot;math inline&quot;&gt;\(\mathscr{L}\)&lt;/span&gt;
&lt;/td&gt;
&lt;td&gt;
Y
&lt;/td&gt;
&lt;td&gt;
&lt;span class=&quot;math inline&quot;&gt;\(\mathscr{Y}\)&lt;/span&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
M
&lt;/td&gt;
&lt;td&gt;
&lt;span class=&quot;math inline&quot;&gt;\(\mathscr{M}\)&lt;/span&gt;
&lt;/td&gt;
&lt;td&gt;
Z
&lt;/td&gt;
&lt;td&gt;
&lt;span class=&quot;math inline&quot;&gt;\(\mathscr{Z}\)&lt;/span&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;p&gt;Alternatively, use the excellent &lt;a
href=&quot;http://detexify.kirelabs.org/classify.html&quot;&gt;Detexify&lt;/a&gt; tool:&lt;/p&gt;
&lt;figure&gt;
&lt;img src=&quot;/img/mathscr-detexify.png&quot; /&gt;
&lt;/figure&gt;
&lt;p&gt;The formal script typeface is available in LaTeX using the
&lt;code&gt;\mathscr&lt;/code&gt; command from the &lt;code&gt;mathrsfs&lt;/code&gt;
package:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;\usepackage{mathrsfs}

$\mathscr{Q}$&lt;/code&gt;&lt;/pre&gt;
</description>
                        <pubDate>Fri, 11 May 2018 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2018-05-11-weird-math-letters</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2018-05-11-weird-math-letters.html</guid>
                </item>
        
                <item>
                        <title>GHC-style note snippet for Vim</title>
                        <description>&lt;p&gt;I am a big fan of GHC-style notes. Notes are a convention for long,
in-depth comments that do not interrupt the flow of the code.&lt;/p&gt;
&lt;p&gt;A note is a comment that is formatted to be easily searchable and
recognizable:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb1&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb1-1&quot;&gt;&lt;a href=&quot;#cb1-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;co&quot;&gt;{- Note [Extra args in rule matching]&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-2&quot;&gt;&lt;a href=&quot;#cb1-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;co&quot;&gt;   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-3&quot;&gt;&lt;a href=&quot;#cb1-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;co&quot;&gt;   If we find a matching rule, we return (Just (rule, rhs)),&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-4&quot;&gt;&lt;a href=&quot;#cb1-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;co&quot;&gt;   but the rule firing has only consumed as many of the input args&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-5&quot;&gt;&lt;a href=&quot;#cb1-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;co&quot;&gt;   as the ruleArity says.  It&amp;#39;s up to the caller to keep track&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-6&quot;&gt;&lt;a href=&quot;#cb1-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;co&quot;&gt;   of any left-over args.  E.g. if you call&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-7&quot;&gt;&lt;a href=&quot;#cb1-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;co&quot;&gt;       lookupRule ... f [e1, e2, e3]&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-8&quot;&gt;&lt;a href=&quot;#cb1-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;co&quot;&gt;   and it returns Just (r, rhs), where r has ruleArity 2&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-9&quot;&gt;&lt;a href=&quot;#cb1-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;co&quot;&gt;   then the real rewrite is&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-10&quot;&gt;&lt;a href=&quot;#cb1-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;co&quot;&gt;       f e1 e2 e3 ==&amp;gt; rhs e3&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-11&quot;&gt;&lt;a href=&quot;#cb1-11&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;co&quot;&gt;-}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;A note can be referenced in the code like this:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb2&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb2-1&quot;&gt;&lt;a href=&quot;#cb2-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;lookupRule ::&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;Activation&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Bool&lt;/span&gt;) &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;InScopeSet&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-2&quot;&gt;&lt;a href=&quot;#cb2-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;        &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Id&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; [&lt;span class=&quot;dt&quot;&gt;CoreExpr&lt;/span&gt;]&lt;/span&gt;
&lt;span id=&quot;cb2-3&quot;&gt;&lt;a href=&quot;#cb2-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;        &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; [&lt;span class=&quot;dt&quot;&gt;CoreRule&lt;/span&gt;] &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Maybe&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;CoreRule&lt;/span&gt;, &lt;span class=&quot;dt&quot;&gt;CoreExpr&lt;/span&gt;)&lt;/span&gt;
&lt;span id=&quot;cb2-4&quot;&gt;&lt;a href=&quot;#cb2-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;co&quot;&gt;-- See Note [Extra args in rule matching]&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-5&quot;&gt;&lt;a href=&quot;#cb2-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;lookupRule is_active in_scope fn args rules&lt;/span&gt;
&lt;span id=&quot;cb2-6&quot;&gt;&lt;a href=&quot;#cb2-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;case&lt;/span&gt; go [] rules &lt;span class=&quot;kw&quot;&gt;of&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-7&quot;&gt;&lt;a href=&quot;#cb2-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    []     &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Nothing&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-8&quot;&gt;&lt;a href=&quot;#cb2-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    (m&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt;ms) &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Just&lt;/span&gt; (findBest (fn,args) m ms)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This convention for notes was originally developed for GHC, but it
can be used in absolutely any project and in any programming language.
You can read more about notes in the &lt;a
href=&quot;https://ghc.haskell.org/trac/ghc/wiki/Commentary/CodingStyle#Commentsinthesourcecode&quot;&gt;GHC
commentary&lt;/a&gt; and in &lt;a href=&quot;http://www.aosabook.org/en/ghc.html&quot;&gt;The
Architecture of Open Source Applications&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The only issue I used to have with notes was that I could never
remember how to format them properly, so every time I wanted to insert
one, I would find and copy-paste one either from my own code or from the
GHC source.&lt;/p&gt;
&lt;p&gt;This motivated me to create a SnipMate snippet for Vim that automates
the process.&lt;/p&gt;
&lt;p&gt;Here are the steps:&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;&lt;p&gt;Install &lt;a
href=&quot;https://github.com/garbas/vim-snipmate&quot;&gt;SnipMate&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Make sure it uses the new snippet parser. Put&lt;/p&gt;
&lt;pre class=&quot;vim&quot;&gt;&lt;code&gt;let g:snipMate = { &amp;#39;snippet_version&amp;#39;: 1 }&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;in your &lt;code&gt;~/.vimrc&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Run&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;base64 -d &amp;gt;&amp;gt; ~/.vim/snippets/haskell.snippets &amp;lt;&amp;lt;EOF
c25pcHBldCBOb3RlCgktLSBTZWUgTm90ZSBbJHsxOnRpdGxlfV0KCXstIE5vdGUgWyQxXQoJICAg
fn5+fn5+fiR7MS8uL34vZ30KCSAgICR7Mjp0ZXh0fQoJLX0K
EOF&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;(The reason for base64 is to preserve the relevant tab
characters.)&lt;/p&gt;
&lt;p&gt;This will install the following snippet:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;snippet Note
  -- See Note [${1:title}]
  {- Note [$1]
     ~~~~~~~${1/./~/g}
     ${2:text}
  -}&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Now you are ready to insert a note. Open a Haskell file in Vim and
type&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Note&amp;lt;Tab&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This will expand into a template&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;-- See Note [title]
{- Note [title]
   ~~~~~~~~~~~~
   text
-}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Just start typing the title of the note, and it will replace both
occurrences of &lt;code&gt;title&lt;/code&gt; at the same time. Then press
&lt;code&gt;&amp;lt;Tab&amp;gt;&lt;/code&gt;, and start typing in the text of the note.&lt;/p&gt;
&lt;p&gt;The snippet consists of two part: the note itself, and the reference
to the note. You leave one in place and cut-and-paste the other one to
where you want it to be.&lt;/p&gt;
&lt;figure&gt;
&lt;video src=&quot;/img/vim-note-screencast.mp4&quot; muted controls preload&gt;
&lt;/video&gt;
&lt;/figure&gt;
</description>
                        <pubDate>Wed, 02 May 2018 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2018-05-02-ghc-note-snippet</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2018-05-02-ghc-note-snippet.html</guid>
                </item>
        
                <item>
                        <title>Is differentiability arbitrary?</title>
                        <description>&lt;p&gt;A function &lt;span class=&quot;math inline&quot;&gt;\(f\)&lt;/span&gt; is called
differentiable at point &lt;span class=&quot;math inline&quot;&gt;\(x_0\)&lt;/span&gt; if it
can be approximated by a linear function near &lt;span
class=&quot;math inline&quot;&gt;\(x_0\)&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;More formally, &lt;span class=&quot;math inline&quot;&gt;\(f\)&lt;/span&gt; is
differentiable at &lt;span class=&quot;math inline&quot;&gt;\(x_0\)&lt;/span&gt; iff for some
number &lt;span class=&quot;math inline&quot;&gt;\(A\)&lt;/span&gt; and for all &lt;span
class=&quot;math inline&quot;&gt;\(x\)&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;math display&quot;&gt;\[
f(x)=f(x_0)+A\cdot(x-x_0) + o(x-x_0).
\]&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Here &lt;span class=&quot;math inline&quot;&gt;\(f(x_0)+A\cdot(x-x_0)\)&lt;/span&gt; is the
linear function of &lt;span class=&quot;math inline&quot;&gt;\(x\)&lt;/span&gt; that
approximates &lt;span class=&quot;math inline&quot;&gt;\(f(x)\)&lt;/span&gt; near &lt;span
class=&quot;math inline&quot;&gt;\(x_0\)&lt;/span&gt;, and &lt;span
class=&quot;math inline&quot;&gt;\(o(x-x_0)\)&lt;/span&gt; is the approximation error — a
function of &lt;span class=&quot;math inline&quot;&gt;\(x\)&lt;/span&gt; &lt;a
href=&quot;http://mathworld.wolfram.com/Little-ONotation.html&quot;&gt;such that&lt;/a&gt;
&lt;span class=&quot;math inline&quot;&gt;\(\frac{o(x-x_0)}{x-x_0}\)&lt;/span&gt; tends to 0
when &lt;span class=&quot;math inline&quot;&gt;\(x-x_0\)&lt;/span&gt; tends to 0.&lt;/p&gt;
&lt;p&gt;There is something arbitrary about this definition. Why are we
approximating &lt;span class=&quot;math inline&quot;&gt;\(f\)&lt;/span&gt; by a linear
function, and not by the square function &lt;span
class=&quot;math inline&quot;&gt;\(x^2\)&lt;/span&gt;, or the square root function &lt;span
class=&quot;math inline&quot;&gt;\(\sqrt{x}\)&lt;/span&gt;, or the sine function &lt;span
class=&quot;math inline&quot;&gt;\(\sin x\)&lt;/span&gt;?&lt;/p&gt;
&lt;p&gt;In my experience, this is almost never explained by high school
teachers or university professors who introduce differentiability to
students. At best they may say that linear functions play a very
important role in mathematics which, while true, is just begging the
question.&lt;/p&gt;
&lt;h2 id=&quot;approximating-by-the-square-function&quot;&gt;Approximating by the
square function&lt;/h2&gt;
&lt;p&gt;If a function can be approximated by the square function, i.e.&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;math display&quot;&gt;\[
f(x)=f(x_0)+B\cdot(x-x_0)^2 + o((x-x_0)^2),
\]&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;then it can also be appoximated by a linear function — or, more
specifically, a constant function &lt;span
class=&quot;math inline&quot;&gt;\(f(x_0)\)&lt;/span&gt;. This is because &lt;span
class=&quot;math inline&quot;&gt;\((x-x_0)^2=o(x-x_0)\)&lt;/span&gt;, so the whole term
&lt;span class=&quot;math inline&quot;&gt;\(B\cdot(x-x_0)^2 + o((x-x_0)^2)\)&lt;/span&gt; can
put into the approximation error &lt;span
class=&quot;math inline&quot;&gt;\(o(x-x_0)\)&lt;/span&gt; in the usual definition, and
&lt;span class=&quot;math inline&quot;&gt;\(A\)&lt;/span&gt; can be set to zero.&lt;/p&gt;
&lt;p&gt;Conversely, if a function is differentiable and its derivative is
zero, then it can be approximated by the quadratic function.&lt;/p&gt;
&lt;h2 id=&quot;approximating-by-the-square-root-function&quot;&gt;Approximating by the
square root function&lt;/h2&gt;
&lt;p&gt;Consider a function that can be approximated by the square root
function:&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;math display&quot;&gt;\[
f(x)=f(x_0)+B\cdot\sqrt{x-x_0} + o(\sqrt{x-x_0}).
\]&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;An example would be the square function itself, &lt;span
class=&quot;math inline&quot;&gt;\(f(x)=\sqrt{x}\)&lt;/span&gt;, near &lt;span
class=&quot;math inline&quot;&gt;\(x_0=0\)&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;But is this property “sustainable”? It can hold at a single point
&lt;span class=&quot;math inline&quot;&gt;\(x_0\)&lt;/span&gt;, but can it hold for all points
in an interval in the same way as a function can be differentiable at
all points of an interval?&lt;/p&gt;
&lt;p&gt;Suppose that&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;math display&quot;&gt;\[
f(x)=f(x_0)+B(x_0)\cdot\sqrt{x-x_0} + o(\sqrt{x-x_0})
\]&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;for all &lt;span class=&quot;math inline&quot;&gt;\(x_0\)&lt;/span&gt; in &lt;span
class=&quot;math inline&quot;&gt;\([a,b]\)&lt;/span&gt;. Pick an integer &lt;span
class=&quot;math inline&quot;&gt;\(M&amp;gt;0\)&lt;/span&gt; and divide &lt;span
class=&quot;math inline&quot;&gt;\([a,b]\)&lt;/span&gt; into &lt;span
class=&quot;math inline&quot;&gt;\(M\)&lt;/span&gt; equal sub-intervals &lt;span
class=&quot;math display&quot;&gt;\[\left[a+(b-a)\cdot \frac{m}{M}, a+(b-a)\cdot
\frac{m+1}M\right],\]&lt;/span&gt; &lt;span class=&quot;math inline&quot;&gt;\(0\leq m\leq
M-1\)&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;Then&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;math display&quot;&gt;\[
\begin{split}
f(b)-f(a)
&amp;amp; =\sum_{m=0}^{M-1} f\left(a+(b-a)\cdot
\frac{m+1}M\right)-f\left(a+(b-a)\cdot \frac{m}{M}\mathstrut\right) \\
&amp;amp; =\sum_{m=0}^{M-1} B\left(a+(b-a)\cdot
\frac{m}M\right)\sqrt{\frac{b-a}M} + o(1/M).
\end{split}
\]&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;You can already notice that something is strange. Suppose that &lt;span
class=&quot;math inline&quot;&gt;\(B(x)\)&lt;/span&gt; does not depend on &lt;span
class=&quot;math inline&quot;&gt;\(x\)&lt;/span&gt;, &lt;span class=&quot;math inline&quot;&gt;\(B(x)\equiv
B\)&lt;/span&gt;. Then the right-hand side above reduces to &lt;span
class=&quot;math inline&quot;&gt;\(B\sqrt{M(b-a)}+o(1/M)\)&lt;/span&gt; and goes to
infinity as &lt;span class=&quot;math inline&quot;&gt;\(M\)&lt;/span&gt; increases; it cannot
possibly remain equal to &lt;span
class=&quot;math inline&quot;&gt;\(f(b)-f(a)\)&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;More generally (but for the same reason), there can’t be any point on
&lt;span class=&quot;math inline&quot;&gt;\([a,b]\)&lt;/span&gt; where &lt;span
class=&quot;math inline&quot;&gt;\(B\)&lt;/span&gt; is continuous and not equal to 0, or
any sub-interval of &lt;span class=&quot;math inline&quot;&gt;\([a,b]\)&lt;/span&gt; where
&lt;span class=&quot;math inline&quot;&gt;\(B(x)&amp;gt;\epsilon&amp;gt;0\)&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;So this approximation is rather weird unless &lt;span
class=&quot;math inline&quot;&gt;\(B(x)\equiv 0\)&lt;/span&gt;.&lt;/p&gt;
&lt;h2 id=&quot;approximating-by-the-sine-function&quot;&gt;Approximating by the sine
function&lt;/h2&gt;
&lt;p&gt;What happens if we try to approximate by, say, &lt;span
class=&quot;math inline&quot;&gt;\(\sin x\)&lt;/span&gt;?&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;math display&quot;&gt;\[
f(x)=f(x_0)+B\cdot\sin(x-x_0) + o(\sin(x-x_0)).
\]&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;To be careful, we need to restrict this approximation to &lt;span
class=&quot;math inline&quot;&gt;\(x\)&lt;/span&gt; in some neighborhood of &lt;span
class=&quot;math inline&quot;&gt;\(x_0\)&lt;/span&gt;. We didn’t have to do this before
because when &lt;span class=&quot;math inline&quot;&gt;\(x\)&lt;/span&gt; is not close to
&lt;span class=&quot;math inline&quot;&gt;\(x_0\)&lt;/span&gt;, &lt;span
class=&quot;math inline&quot;&gt;\(o((x-x_0)^{\alpha})\)&lt;/span&gt; can be anything at
all. Here, however, &lt;span class=&quot;math inline&quot;&gt;\(\sin(x-x_0)\)&lt;/span&gt; can
be small even if &lt;span class=&quot;math inline&quot;&gt;\(x-x_0\)&lt;/span&gt; is not
small.&lt;/p&gt;
&lt;p&gt;We know that &lt;span class=&quot;math inline&quot;&gt;\(\sin x\)&lt;/span&gt; is itself
differentiable in the usual sense, its derivative at 0 being 1:&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;math display&quot;&gt;\[
\sin (x-x_0)=(x-x_0) + o(x-x_0).
\]&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Therefore,&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;math display&quot;&gt;\[
f(x)=f(x_0)+B\cdot(x-x_0) + o(x-x_0),
\]&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;i.e. &lt;span class=&quot;math inline&quot;&gt;\(f\)&lt;/span&gt; is differentiable in the
usual sense as well, and vice versa.&lt;/p&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Generalizing from these examples, let’s say that we approximate a
function &lt;span class=&quot;math inline&quot;&gt;\(f\)&lt;/span&gt; with a function &lt;span
class=&quot;math inline&quot;&gt;\(g\)&lt;/span&gt; in the neighborhood of &lt;span
class=&quot;math inline&quot;&gt;\(x_0\)&lt;/span&gt;:&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;math display&quot;&gt;\[
f(x)=f(x_0)+B\cdot g(x-x_0) + o(g(x-x_0)),
\]&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;where &lt;span class=&quot;math inline&quot;&gt;\(g(0)=0\)&lt;/span&gt; so that &lt;span
class=&quot;math inline&quot;&gt;\(o(g(x-x_0))\)&lt;/span&gt; has the usual meaning.&lt;/p&gt;
&lt;p&gt;Then:&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;If &lt;span class=&quot;math inline&quot;&gt;\(g\)&lt;/span&gt; is itself differentiable
at 0 and &lt;span class=&quot;math inline&quot;&gt;\(g&amp;#39;(0)\neq 0\)&lt;/span&gt; (as in
&lt;span class=&quot;math inline&quot;&gt;\(g(x)=\sin x\)&lt;/span&gt;), we get the usual
class of differentiable functions.&lt;/li&gt;
&lt;li&gt;If &lt;span class=&quot;math inline&quot;&gt;\(g\)&lt;/span&gt; is differentiable at 0 and
&lt;span class=&quot;math inline&quot;&gt;\(g&amp;#39;(0)=0\)&lt;/span&gt; (as in &lt;span
class=&quot;math inline&quot;&gt;\(g(x)=x^2\)&lt;/span&gt;), then we get a subclass of
differentiable functions for which the derivative at &lt;span
class=&quot;math inline&quot;&gt;\(x_0\)&lt;/span&gt; is 0.&lt;/li&gt;
&lt;li&gt;If &lt;span class=&quot;math inline&quot;&gt;\(g\)&lt;/span&gt; itself is not
differentiable at 0 (as in &lt;span class=&quot;math inline&quot;&gt;\(g(x)=\sqrt
x\)&lt;/span&gt;), then this property will hold either at an isolated point or
describe some strange (non-smooth) functions.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;This doesn’t quite tell us why we pick &lt;span
class=&quot;math inline&quot;&gt;\(x\)&lt;/span&gt; instead of &lt;span
class=&quot;math inline&quot;&gt;\(\sin x\)&lt;/span&gt; — the answer would be some
hand-wavy simplicity arguments — but at least it reassures us that we
are not missing much by focusing on linear approximations.&lt;/p&gt;
</description>
                        <pubDate>Tue, 01 May 2018 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2018-05-01-is-differentiability-arbitrary</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2018-05-01-is-differentiability-arbitrary.html</guid>
                </item>
        
                <item>
                        <title>Rational approach to conferences</title>
                        <description>&lt;p&gt;When I went to any conference in the past, I would try to extract the
maximum out of it: stay for the whole duration of the main event and
attend all satellites. Now I think I might change my conference
strategy.&lt;/p&gt;
&lt;p&gt;So what changed?&lt;/p&gt;
&lt;p&gt;Previously, I would stay in hostels, usually €20–25 a night. Once I
travel somewhere for a conference, there is little cost to stay longer
there. In comparison, fixed costs were high. In addition to the cost of
the flight, I needed to apply for a visa to travel anywhere, which
usually cost me €100–200, a trip to an embassy in Kiev, and quite a bit
of time and effort to gather all the necessary documents.&lt;/p&gt;
&lt;p&gt;Now I stay in hotels, usually around €100 per night, which makes the
marginal cost of staying an additional day non-negligible. On the other
hand, I no longer need a visa for short trips to continental Europe, so
that reduces the fixed costs of going to a conference.&lt;/p&gt;
&lt;p&gt;(The argument about the fixed costs sounds like a sunk cost fallacy:
because I paid for the visa and flight, I now need to stay for the whole
event. Yes, I am susceptible to sunk cost fallacies.)&lt;/p&gt;
&lt;p&gt;Then there is the time itself. When I was younger, I did not value my
time too much and probably didn’t have better alternatives than to stay
in a different country and attend another day of the conference.
Nowadays, I’d rather do some work, spend time with my family, or
study.&lt;/p&gt;
&lt;p&gt;Finally, thanks to my past experiences, I can now better predict what
I get the most value from, and when the diminishing returns kick in. The
best time at a conference for me is the first 2–3 days. This is when I
am fresh and excited. After these first few days I get tired, going to
the talks becomes a chore, and I’d rather sleep in than attend a
keynote.&lt;/p&gt;
&lt;p&gt;Another observation is that when an event has satellites, the
satellites are usually more interesting to me than the main event. I
don’t know how universal this is, but I found it true about &lt;a
href=&quot;https://www.icfpconference.org/&quot;&gt;ICFP&lt;/a&gt; and &lt;a
href=&quot;https://www.recomb.org/home&quot;&gt;RECOMB&lt;/a&gt;. That the satellites are
usually cheaper to attend than the main event is a nice bonus.&lt;/p&gt;
&lt;p&gt;So for future conferences, I am going to only attend the satellites
or, if there are no satellites, limit my attendance to the 2–3 most
interesting days of the conference. This may allow me to go to a larger
number of conferences. That said, I should also conduct due diligence on
the content/programme of the conferences I plan to attend. Some of the
events I went to this year were so disappointing that they mostly
weren’t worth attending even for a day.&lt;/p&gt;
</description>
                        <pubDate>Sun, 22 Apr 2018 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2018-04-22-rational-approach-to-conferences</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2018-04-22-rational-approach-to-conferences.html</guid>
                </item>
        
                <item>
                        <title>Seneca on social networks</title>
                        <description>&lt;p&gt;The recent scandal around Facebook brought up many discussions on how
apparently free things do have a price. But it’s nothing new, really;
Seneca warned us about it two thousand years ago.&lt;/p&gt;
&lt;blockquote&gt;
&lt;ol start=&quot;7&quot; type=&quot;1&quot;&gt;
&lt;li&gt;&lt;p&gt;Our stupidity may be clearly proved by the fact that we hold that
“buying” refers only to the objects for which we pay cash, and we regard
as free gifts the things for which we spend our very selves. These we
should refuse to buy, if we were compelled to give in payment for them
our houses or some attractive and profitable estate; but we are eager to
attain them at the cost of anxiety, of danger, and of lost honour,
personal freedom, and time; so true it is that each man regards nothing
as cheaper than himself.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Let us therefore act, in all our plans and conduct, just as we
are accustomed to act whenever we approach a huckster who has certain
wares for sale; let us see how much we must pay for that which we crave.
Very often the things that cost nothing cost us the most heavily; I can
show you many objects the quest and acquisition of which have wrested
freedom from our hands. We should belong to ourselves, if only these
things did not belong to us.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;— &lt;a
href=&quot;https://en.wikisource.org/wiki/Moral_letters_to_Lucilius/Letter_42&quot;&gt;Seneca.
Moral letters to Lucilius. Letter 42: On values.&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
</description>
                        <pubDate>Sat, 14 Apr 2018 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2018-04-14-seneca-on-social-networks</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2018-04-14-seneca-on-social-networks.html</guid>
                </item>
        
                <item>
                        <title>The correct way to mark formulas in LaTeX</title>
                        <description>&lt;p&gt;The first thing I learned when I was introduced to LaTeX in 2003 was
that you put inline formulas in &lt;code&gt;$...$&lt;/code&gt; and display formulas
in &lt;code&gt;$$...$$&lt;/code&gt;. Over the years I became aware of the
alternative forms, &lt;code&gt;\(...\)&lt;/code&gt; and &lt;code&gt;\[...\]&lt;/code&gt;, but I
found them ugly (because they are) and assumed they were relics from the
early days of TeX, sort of like &lt;a
href=&quot;https://en.wikipedia.org/wiki/Digraphs_and_trigraphs#C&quot;&gt;trigraphs
in C&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;As it turns out, it’s all exactly the other way around.
&lt;code&gt;$...$&lt;/code&gt; and &lt;code&gt;$$...$$&lt;/code&gt; are the old TeX syntax;
&lt;code&gt;\(...\)&lt;/code&gt; and &lt;code&gt;\[...\]&lt;/code&gt; are the new LaTeX
syntax.&lt;/p&gt;
&lt;p&gt;Couldn’t Leslie Lamport think of a better syntax? I bet he could; he
just couldn’t implement it. These days if we don’t like a language, we
create a new one, with its own parser. But Lamport’s LaTeX is not a new
language. It is a set of macros that work on top of Knuth’s TeX. What
LaTeX has achieved is a testament to TeX’s flexibility and Lamport’s
ingenuity. The &lt;code&gt;\[...\]&lt;/code&gt; “syntax” is just a pair of TeX
macros, &lt;code&gt;\[&lt;/code&gt; and &lt;code&gt;\]&lt;/code&gt;, and like all other control
sequences they have to start with a backslash.&lt;/p&gt;
&lt;p&gt;So why should we prefer Lamport’s ugly &lt;code&gt;\(...\)&lt;/code&gt; and
&lt;code&gt;\[...\]&lt;/code&gt; to Knuth’s beautiful &lt;code&gt;$...$&lt;/code&gt; and
&lt;code&gt;$$...$$&lt;/code&gt;?&lt;/p&gt;
&lt;p&gt;You can find the exact details in the answers to the following TeX.SE
questions:&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://tex.stackexchange.com/q/503/5814&quot;&gt;Why is \[ … \]
preferable to $$ … $$?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://tex.stackexchange.com/q/510/5814&quot;&gt;Are \( and \)
preferable to dollar signs for math mode?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://tex.stackexchange.com/q/40492/5814&quot;&gt;What are the
differences between $$, \[, align, equation and displaymath?&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Another good reference is &lt;a
href=&quot;http://mirrors.rit.edu/CTAN/info/l2tabu/english/l2tabuen.pdf&quot;&gt;An
essential guide to LaTeX2ε usage: Obsolete commands and
packages&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;It boils down to the fact that &lt;code&gt;\(...\)&lt;/code&gt; and
&lt;code&gt;\[...\]&lt;/code&gt; can be (and are) redefined by packages, whereas
&lt;code&gt;$...$&lt;/code&gt; and &lt;code&gt;$$...$$&lt;/code&gt; can’t.&lt;/p&gt;
&lt;p&gt;The main example you’ll find in the above TeX.SE discussion is that
&lt;code&gt;$$...$$&lt;/code&gt;, when used between paragraphs, inserts unwanted
white space; so &lt;code&gt;\[...\]&lt;/code&gt; is (re)defined to suppress it.&lt;/p&gt;
&lt;p&gt;The specific problem I had with &lt;code&gt;$$...$$&lt;/code&gt; is that it &lt;a
href=&quot;https://tex.stackexchange.com/q/25784/5814&quot;&gt;breaks the
&lt;code&gt;lineno&lt;/code&gt; package&lt;/a&gt;, which is used to add line numbers to
the output document. The lines preceding a display formula don’t get
numbered:&lt;/p&gt;
&lt;figure&gt;
&lt;img src=&quot;/img/lineno-bug.svg&quot; alt=&quot;Example from the lineno manual.&quot; /&gt;
&lt;figcaption aria-hidden=&quot;true&quot;&gt;Example from the lineno
manual.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;This is a problem with all the equation environments, as described in
the &lt;a
href=&quot;http://texdoc.net/texmf-dist/doc/latex/lineno/ulineno.pdf&quot;&gt;lineno
manual&lt;/a&gt;, section 7.1. &lt;code&gt;lineno&lt;/code&gt; redefines the
&lt;code&gt;\[&lt;/code&gt; and &lt;code&gt;\]&lt;/code&gt; macros and &lt;code&gt;displaymath&lt;/code&gt;,
&lt;code&gt;equation&lt;/code&gt;, &lt;code&gt;eqnarray&lt;/code&gt;, and &lt;code&gt;eqnarray*&lt;/code&gt;
environments to work around this issue. But &lt;code&gt;lineno&lt;/code&gt; can’t
redefine the &lt;code&gt;$$...$$&lt;/code&gt; syntax; hence if you use it, it’ll
break the numbering. (Oddly enough, &lt;code&gt;lineno&lt;/code&gt; also &lt;a
href=&quot;https://tex.stackexchange.com/q/237243/5814&quot;&gt;doesn’t redefine the
&lt;code&gt;equation*&lt;/code&gt; environment&lt;/a&gt;, which is another problem I’ve
run into.)&lt;/p&gt;
&lt;p&gt;Here’s a cool thing: &lt;a href=&quot;https://pandoc.org/&quot;&gt;pandoc&lt;/a&gt; will
automatically emit the new LaTeX formula syntax regardless of what
syntax you use in the input file. This means you can continue to use
&lt;code&gt;$&lt;/code&gt; and &lt;code&gt;$$&lt;/code&gt; in markdown and get the correct
result:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% echo &amp;#39;$$a^2+b^2=c^2$$&amp;#39; | pandoc -f markdown -t latex
\[a^2+b^2=c^2\]&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If you feel adventurous, you could even filter your LaTeX source
through pandoc:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% echo &amp;#39;$$a^2+b^2=c^2$$&amp;#39; | pandoc -f latex -t latex
\[a^2+b^2=c^2\]&lt;/code&gt;&lt;/pre&gt;
</description>
                        <pubDate>Thu, 12 Apr 2018 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2018-04-12-correct-latex-formula-syntax</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2018-04-12-correct-latex-formula-syntax.html</guid>
                </item>
        
                <item>
                        <title>Install all R packages used in the code</title>
                        <description>&lt;p&gt;Here is a one-liner I use to install all R dependencies of a script.
It is especially useful if you need to run your code on a server or
cluster.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;perl -lne &amp;#39;/library\((.*)\)/ &amp;amp;&amp;amp; print $1&amp;#39; *.R *.Rmd | xargs Rscript -e &amp;#39;install.packages(commandArgs(T), repos = &amp;quot;https://cran.rstudio.com&amp;quot;)&amp;#39;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;An alternative is to use &lt;code&gt;p_load&lt;/code&gt; from the &lt;a
href=&quot;https://cran.r-project.org/web/packages/pacman/vignettes/Introduction_to_pacman.html&quot;&gt;pacman&lt;/a&gt;
package in your R scripts instead of &lt;code&gt;library&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;See also the discussion in &lt;a
href=&quot;https://stackoverflow.com/a/4090208/110081&quot;&gt;Elegant way to check
for missing packages and install them?&lt;/a&gt;.&lt;/p&gt;
</description>
                        <pubDate>Mon, 02 Apr 2018 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2018-04-02-install-r-packages</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2018-04-02-install-r-packages.html</guid>
                </item>
        
                <item>
                        <title>Fighting referral spam</title>
                        <description>&lt;p&gt;Occasionally I like to look through this site’s http logs to get an
idea of how many people read my articles and find out when someone links
to one of them.&lt;/p&gt;
&lt;p&gt;At some point I noticed that the visitor numbers inflated and most
referrers became fake. But this wasn’t the referral spam that I was used
to, when the referrer points to the spammer’s website.&lt;/p&gt;
&lt;p&gt;Quite the opposite, referrals often pointed to other Haskell-related
blogs — byorgey.wordpress.com, blog.ezyang.com, blog.plover.com etc. I
suspect these were harvested from Planet Haskell.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/img/fake-referrers.png&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Yet it was clear that the referrers were fake. The referring and
referred articles were not related in any meaningful way, and upon
inspection the referring articles indeed did not refer to this site. For
example, the logs indicated that Mark Dominus linked to my &lt;a
href=&quot;/articles/2018-02-03-stableptr-undefined-behavior&quot;&gt;article about
stable pointers&lt;/a&gt; from &lt;a
href=&quot;https://blog.plover.com/lang/Turkish-John-Doe.html&quot;&gt;his article
about a Turkish John Doe&lt;/a&gt;, or that FPComplete found my &lt;a
href=&quot;/articles/2017-12-04-golden-tests&quot;&gt;intro to golden tests&lt;/a&gt;
integral to &lt;a
href=&quot;https://www.fpcomplete.com/blog/devops-value-how-to-measure-the-success-of-devops&quot;&gt;measuring
the success of devops&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;But that left me puzzled — if this was spam, where’s the message? Who
would profit from sending me to these seemingly relevant but unrelated
articles on legit blogs?&lt;/p&gt;
&lt;p&gt;My searches led me to &lt;a
href=&quot;https://medium.com/@stijlbreuk/the-state-of-referrerspamblocker-com-614057da5c1d&quot;&gt;this
article&lt;/a&gt; by now defunct project Referrerspamblocker.com. Turns out
the message is nowadays placed in the http headers such as
Accept-Language, which are not traditionally logged by the web servers
but shown by the spammers’ main target, Google Analytics.&lt;/p&gt;
&lt;p&gt;&lt;img
src=&quot;https://cdn-images-1.medium.com/max/1200/1*0f1Htl-uye9j32blkAhJEg.png&quot; /&gt;&lt;/p&gt;
&lt;h2 id=&quot;finding-spammers-ip-addresses&quot;&gt;Finding spammers’ IP
addresses&lt;/h2&gt;
&lt;p&gt;Most of the spam IP addresses I observed came from two hosting
providers: &lt;a href=&quot;https://en.wikipedia.org/wiki/OVH&quot;&gt;OVH&lt;/a&gt; and &lt;a
href=&quot;https://www.online.net/en&quot;&gt;Online SAS&lt;/a&gt;. Both companies are
French, and both have been noticed by webmasters before (&lt;a
href=&quot;http://www.shift8creative.com/posts/detecting-fake-traffic-by-fake-marketers/&quot;&gt;OVH&lt;/a&gt;,
&lt;a
href=&quot;https://www.en.advertisercommunity.com/t5/Google-Analytics-Referral-Spam/Anyone-else-know-Online-SAS/td-p/1180033&quot;&gt;Online
SAS&lt;/a&gt;). A small fraction of spam requests also came from Tiscali
France B2B, apparently a French division of an Italian telecom
company.&lt;/p&gt;
&lt;p&gt;So I needed to collect the IP addresses that belong to these hosting
providers. Since they are not ISPs, I was not worried about blocking
legitimate users.&lt;/p&gt;
&lt;p&gt;Once I had the IP addresses, I could&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;clean up the existing http logs, and&lt;/li&gt;
&lt;li&gt;block the future spam traffic to avoid wasting resources.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;I used the method described &lt;a
href=&quot;/articles/2017-07-14-all-vk.com-ip-addresses&quot;&gt;here&lt;/a&gt; to extract
all RIPE addresses whose maintainers matched
&lt;code&gt;(?:OVH|ONLINESAS)-MNT|MNT-TISCALIFR-B2B&lt;/code&gt;. All of these are
French companies, so most of their IP addresses are in the RIPE
database.&lt;/p&gt;
&lt;p&gt;However, OVH also has some Canadian IPs, which are covered by ARIN.
Sadly, ARIN &lt;a
href=&quot;https://networkengineering.stackexchange.com/questions/29125/arin-ip-database&quot;&gt;does
not provide its IP address database&lt;/a&gt; for bulk download like RIPE
does. For now I manually added the block &lt;code&gt;158.69.0.0/16&lt;/code&gt;,
which I recovered via WHOIS from a couple of IP addresses in my
logs.&lt;/p&gt;
&lt;p&gt;You can download the final list of IPv4 ranges &lt;a
href=&quot;/files/2018-03-25-fighting-referral-spam/refspam.txt&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;cleaning-up-the-existing-logs&quot;&gt;Cleaning up the existing
logs&lt;/h2&gt;
&lt;p&gt;I used the R packages &lt;code&gt;iptools&lt;/code&gt;, &lt;code&gt;purrr&lt;/code&gt;, and
&lt;code&gt;dplyr&lt;/code&gt; to filter the referral spam:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb1&quot;&gt;&lt;pre class=&quot;sourceCode r&quot;&gt;&lt;code class=&quot;sourceCode r&quot;&gt;&lt;span id=&quot;cb1-1&quot;&gt;&lt;a href=&quot;#cb1-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;refspam_ranges &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;scan&lt;/span&gt;(&lt;span class=&quot;st&quot;&gt;&amp;quot;refspam.txt&amp;quot;&lt;/span&gt;, &lt;span class=&quot;at&quot;&gt;what=&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;character&lt;/span&gt;())&lt;/span&gt;
&lt;span id=&quot;cb1-2&quot;&gt;&lt;a href=&quot;#cb1-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;is_refspam_ip &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;cf&quot;&gt;function&lt;/span&gt;(ips) {&lt;/span&gt;
&lt;span id=&quot;cb1-3&quot;&gt;&lt;a href=&quot;#cb1-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;fu&quot;&gt;map&lt;/span&gt;(refspam_ranges, &lt;span class=&quot;cf&quot;&gt;function&lt;/span&gt;(range) &lt;span class=&quot;fu&quot;&gt;ip_in_range&lt;/span&gt;(ips, range)) &lt;span class=&quot;sc&quot;&gt;%&amp;gt;%&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-4&quot;&gt;&lt;a href=&quot;#cb1-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;fu&quot;&gt;reduce&lt;/span&gt;(&lt;span class=&quot;st&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;at&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;st&quot;&gt;`&lt;/span&gt;)&lt;/span&gt;
&lt;span id=&quot;cb1-5&quot;&gt;&lt;a href=&quot;#cb1-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;}&lt;/span&gt;
&lt;span id=&quot;cb1-6&quot;&gt;&lt;a href=&quot;#cb1-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;remove_refspam &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;cf&quot;&gt;function&lt;/span&gt;(d) &lt;span class=&quot;fu&quot;&gt;filter&lt;/span&gt;(d, &lt;span class=&quot;sc&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;is_refspam_ip&lt;/span&gt;(address))&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;blocking-the-spam-using-firewalld&quot;&gt;Blocking the spam using
firewalld&lt;/h2&gt;
&lt;p&gt;I expect something like this to work:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;xargs -n 1 -I{} firewall-cmd --permanent --add-rich-rule=&amp;quot;rule family=&amp;#39;ipv4&amp;#39; source address=&amp;#39;{}&amp;#39; drop&amp;quot; &amp;lt; refspam.txt&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;But I haven’t blocked them just yet. Instead, I’ve added
&lt;code&gt;$http_accept_language&lt;/code&gt; to the nginx’s
&lt;code&gt;log_format&lt;/code&gt; and am now anxious to finally learn what the
spammers have been trying to tell me for so long.&lt;/p&gt;
&lt;p&gt;Also, see the next section.&lt;/p&gt;
&lt;h2 id=&quot;legitimate-bots&quot;&gt;Legitimate bots&lt;/h2&gt;
&lt;p&gt;&lt;em&gt;(Added on 2018-03-26.)&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Mark Dominus wrote to me to say that he also had this problem and
also added:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Is your idea that because the sources are hosting providers rather
than ISPs, you will only be blocking bots running on hosted services?
But isn’t there still a concern that you might also block legitimate
bots hosted at the same providers?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Fair point. I ran a query to see if there were any self-identified
bots coming from those addresses, and I was very surprised to see so
many (&lt;strong&gt;n&lt;/strong&gt; is the number of requests made in the last 90
days):&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style=&quot;text-align: left;&quot;&gt;agent&lt;/th&gt;
&lt;th style=&quot;text-align: right;&quot;&gt;n&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: left;&quot;&gt;Mozilla/5.0 (compatible; AhrefsBot/5.2;
+&lt;a href=&quot;http://ahrefs.com/robot/&quot;
class=&quot;uri&quot;&gt;http://ahrefs.com/robot/&lt;/a&gt;)&lt;/td&gt;
&lt;td style=&quot;text-align: right;&quot;&gt;2142&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: left;&quot;&gt;Barkrowler/0.7 (+&lt;a
href=&quot;http://www.exensa.com/crawl&quot;
class=&quot;uri&quot;&gt;http://www.exensa.com/crawl&lt;/a&gt;)&lt;/td&gt;
&lt;td style=&quot;text-align: right;&quot;&gt;1387&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: left;&quot;&gt;CommaFeed/2.5.0-SNAPSHOT (&lt;a
href=&quot;https://github.com/Athou/commafeed&quot;
class=&quot;uri&quot;&gt;https://github.com/Athou/commafeed&lt;/a&gt;)&lt;/td&gt;
&lt;td style=&quot;text-align: right;&quot;&gt;398&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: left;&quot;&gt;Mozilla/5.0 (compatible; AhrefsBot/5.2;
News; +&lt;a href=&quot;http://ahrefs.com/robot/&quot;
class=&quot;uri&quot;&gt;http://ahrefs.com/robot/&lt;/a&gt;)&lt;/td&gt;
&lt;td style=&quot;text-align: right;&quot;&gt;296&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: left;&quot;&gt;Mozilla/5.0 (compatible; MJ12bot/v1.4.8;
&lt;a href=&quot;http://mj12bot.com/&quot; class=&quot;uri&quot;&gt;http://mj12bot.com/&lt;/a&gt;)&lt;/td&gt;
&lt;td style=&quot;text-align: right;&quot;&gt;148&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: left;&quot;&gt;Mozilla/5.0 (compatible; MJ12bot/v1.4.7;
&lt;a href=&quot;http://mj12bot.com/&quot; class=&quot;uri&quot;&gt;http://mj12bot.com/&lt;/a&gt;)&lt;/td&gt;
&lt;td style=&quot;text-align: right;&quot;&gt;106&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: left;&quot;&gt;Mozilla/5.0 (compatible; PaperLiBot/2.1;
&lt;a href=&quot;http://support.paper.li/entries/20023257-what-is-paper-li&quot;
class=&quot;uri&quot;&gt;http://support.paper.li/entries/20023257-what-is-paper-li&lt;/a&gt;)&lt;/td&gt;
&lt;td style=&quot;text-align: right;&quot;&gt;64&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: left;&quot;&gt;FeedHQ/2017.07.18.1500363079 (&lt;a
href=&quot;https://github.com/feedhq/feedhq&quot;
class=&quot;uri&quot;&gt;https://github.com/feedhq/feedhq&lt;/a&gt;; ping; &lt;a
href=&quot;https://github.com/feedhq/feedhq/wiki/fetcher&quot;
class=&quot;uri&quot;&gt;https://github.com/feedhq/feedhq/wiki/fetcher&lt;/a&gt;; like
FeedFetcher-Google)&lt;/td&gt;
&lt;td style=&quot;text-align: right;&quot;&gt;32&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: left;&quot;&gt;Mozilla/5.0 (compatible; HackerfallBot;
+&lt;a href=&quot;http://hackerfall.com/help/bot&quot;
class=&quot;uri&quot;&gt;http://hackerfall.com/help/bot&lt;/a&gt;)&lt;/td&gt;
&lt;td style=&quot;text-align: right;&quot;&gt;30&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: left;&quot;&gt;python-requests/2.18.4&lt;/td&gt;
&lt;td style=&quot;text-align: right;&quot;&gt;22&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: left;&quot;&gt;LivelapBot/0.2 (&lt;a
href=&quot;http://site.livelap.com/crawler&quot;
class=&quot;uri&quot;&gt;http://site.livelap.com/crawler&lt;/a&gt;)&lt;/td&gt;
&lt;td style=&quot;text-align: right;&quot;&gt;17&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: left;&quot;&gt;python-requests/2.11.1&lt;/td&gt;
&lt;td style=&quot;text-align: right;&quot;&gt;10&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: left;&quot;&gt;SocialRankIOBot; &lt;a
href=&quot;http://socialrank.io/about&quot;
class=&quot;uri&quot;&gt;http://socialrank.io/about&lt;/a&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: right;&quot;&gt;5&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: left;&quot;&gt;Tiny Tiny RSS/17.12 (e35a467) (&lt;a
href=&quot;http://tt-rss.org/&quot; class=&quot;uri&quot;&gt;http://tt-rss.org/&lt;/a&gt;)&lt;/td&gt;
&lt;td style=&quot;text-align: right;&quot;&gt;3&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: left;&quot;&gt;FeedHQ/2018.03.21.1521618317 (&lt;a
href=&quot;https://github.com/feedhq/feedhq&quot;
class=&quot;uri&quot;&gt;https://github.com/feedhq/feedhq&lt;/a&gt;; ping; &lt;a
href=&quot;https://github.com/feedhq/feedhq/wiki/fetcher&quot;
class=&quot;uri&quot;&gt;https://github.com/feedhq/feedhq/wiki/fetcher&lt;/a&gt;; like
FeedFetcher-Google)&lt;/td&gt;
&lt;td style=&quot;text-align: right;&quot;&gt;2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: left;&quot;&gt;Mozilla/5.0 (compatible; ImageFetcher/7.0;
+&lt;a href=&quot;http://images.weserv.nl/&quot;
class=&quot;uri&quot;&gt;http://images.weserv.nl/&lt;/a&gt;)&lt;/td&gt;
&lt;td style=&quot;text-align: right;&quot;&gt;2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: left;&quot;&gt;Mozilla/5.0 (compatible; yiphysearchbot;
+&lt;a href=&quot;http://37.187.121.74/bot.php&quot;
class=&quot;uri&quot;&gt;http://37.187.121.74/bot.php&lt;/a&gt;)&lt;/td&gt;
&lt;td style=&quot;text-align: right;&quot;&gt;2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: left;&quot;&gt;node-superagent/0.18.2&lt;/td&gt;
&lt;td style=&quot;text-align: right;&quot;&gt;2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: left;&quot;&gt;Python-urllib/3.5&lt;/td&gt;
&lt;td style=&quot;text-align: right;&quot;&gt;2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: left;&quot;&gt;curl/7.57.0&lt;/td&gt;
&lt;td style=&quot;text-align: right;&quot;&gt;1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: left;&quot;&gt;GuzzleHttp/6.2.1 curl/7.47.0
PHP/7.1.11-1+ubuntu16.04.1+deb.sury.org+1&lt;/td&gt;
&lt;td style=&quot;text-align: right;&quot;&gt;1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: left;&quot;&gt;Mozilla/5.0 (compatible; Grobbot/2.2; +&lt;a
href=&quot;https://grob.it&quot; class=&quot;uri&quot;&gt;https://grob.it&lt;/a&gt;)&lt;/td&gt;
&lt;td style=&quot;text-align: right;&quot;&gt;1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: left;&quot;&gt;Tiny Tiny RSS/17.12 (&lt;a
href=&quot;http://tt-rss.org/&quot; class=&quot;uri&quot;&gt;http://tt-rss.org/&lt;/a&gt;)&lt;/td&gt;
&lt;td style=&quot;text-align: right;&quot;&gt;1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: left;&quot;&gt;Wget/1.14 (linux-gnu)&lt;/td&gt;
&lt;td style=&quot;text-align: right;&quot;&gt;1&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Self-identified bots accounted for 14% of all http requests coming
from OVH et al (the rest must be spammers). Most of these bots look
legit. Moreover, several are RSS readers, which I most certainly don’t
want to block. So I won’t be adding any firewall rules after all.&lt;/p&gt;
&lt;h2 id=&quot;are-these-bots-self-aware&quot;&gt;Are these bots self-aware?&lt;/h2&gt;
&lt;p&gt;&lt;em&gt;(Added on 2018-04-08.)&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Since I published this post, the spammy referrers magically
stopped.&lt;/p&gt;
&lt;figure&gt;
&lt;img src=&quot;/img/refspam-stats.svg&quot;
alt=&quot;Number of requests from OVH et al. IP addresses, including those supplying fake referrers and excluding self-identified bots. The blue line marks this post’s publication date.&quot; /&gt;
&lt;figcaption aria-hidden=&quot;true&quot;&gt;Number of requests from OVH et al. IP
addresses, including those supplying fake referrers and excluding
self-identified bots. The blue line marks this post’s publication
date.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;The total number of requests from the identified IP ranges dropped
sharply, and the remaining ones had either no referrer or a sane
referrer like ro-che.info or planet.haskell.org.&lt;/p&gt;
&lt;p&gt;These are some hypotheses as to what could happen, although none of
them strikes me as very likely.&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;These bots are self-aware; they found out that I exposed them and
altered their behavior.&lt;/li&gt;
&lt;li&gt;The bots’ owners found my article and altered their bots’
behavior.&lt;/li&gt;
&lt;li&gt;Around the same time as I wrote this article, I moved the site from
a server in Germany to one in the UK. Was there something preventing the
bots from updating their DNS records for two weeks?&lt;/li&gt;
&lt;li&gt;Or maybe they are not interested in spamming British servers?&lt;/li&gt;
&lt;/ol&gt;
</description>
                        <pubDate>Sun, 25 Mar 2018 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2018-03-25-fighting-referral-spam</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2018-03-25-fighting-referral-spam.html</guid>
                </item>
        
                <item>
                        <title>Notes on Jekyll</title>
                        <description>&lt;p&gt;Here I describe a couple of Jekyll issues that I had to debug
recently.&lt;/p&gt;
&lt;h2 id=&quot;broken-symlinks&quot;&gt;Broken symlinks&lt;/h2&gt;
&lt;p&gt;I have many relative symlinks in my jekyll directory that point
outside of it. For instance, &lt;a
href=&quot;/docs/2010-10-22-posix.pdf&quot;&gt;docs/2010-10-22-posix.pdf&lt;/a&gt; is a
symlink to &lt;code&gt;../../kpi/POSIX/2010-10-22-posix.pdf&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Recently I noticed that these symlinks are broken in jekyll’s
generated directory, &lt;code&gt;_site&lt;/code&gt;. It appears that jekyll copies
the link as is, that is as a relative link to
&lt;code&gt;../../kpi/POSIX/2010-10-22-posix.pdf&lt;/code&gt;, but because the
location of the link changed from &lt;code&gt;$JEKYLL_ROOT&lt;/code&gt; to
&lt;code&gt;$JEKYLL_ROOT/_site&lt;/code&gt;, it no longer pointed into the right
place.&lt;/p&gt;
&lt;p&gt;So I dug into the source code and found this in
&lt;code&gt;lib/jekyll/static_file.rb&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb1&quot;&gt;&lt;pre
class=&quot;sourceCode ruby&quot;&gt;&lt;code class=&quot;sourceCode ruby&quot;&gt;&lt;span id=&quot;cb1-1&quot;&gt;&lt;a href=&quot;#cb1-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;cf&quot;&gt;def&lt;/span&gt; copy_file(dest_path)&lt;/span&gt;
&lt;span id=&quot;cb1-2&quot;&gt;&lt;a href=&quot;#cb1-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;cf&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;@site&lt;/span&gt;&lt;span class=&quot;at&quot;&gt;.safe&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Jekyll&lt;/span&gt;&lt;span class=&quot;at&quot;&gt;.env&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;quot;production&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-3&quot;&gt;&lt;a href=&quot;#cb1-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;dt&quot;&gt;FileUtils&lt;/span&gt;&lt;span class=&quot;at&quot;&gt;.cp&lt;/span&gt;(path, dest_path)&lt;/span&gt;
&lt;span id=&quot;cb1-4&quot;&gt;&lt;a href=&quot;#cb1-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;cf&quot;&gt;else&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-5&quot;&gt;&lt;a href=&quot;#cb1-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;dt&quot;&gt;FileUtils&lt;/span&gt;&lt;span class=&quot;at&quot;&gt;.copy_entry&lt;/span&gt;(path, dest_path)&lt;/span&gt;
&lt;span id=&quot;cb1-6&quot;&gt;&lt;a href=&quot;#cb1-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;cf&quot;&gt;end&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-7&quot;&gt;&lt;a href=&quot;#cb1-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-8&quot;&gt;&lt;a href=&quot;#cb1-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;cf&quot;&gt;unless&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;File&lt;/span&gt;&lt;span class=&quot;at&quot;&gt;.symlink?&lt;/span&gt;(dest_path)&lt;/span&gt;
&lt;span id=&quot;cb1-9&quot;&gt;&lt;a href=&quot;#cb1-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;dt&quot;&gt;File&lt;/span&gt;&lt;span class=&quot;at&quot;&gt;.utime&lt;/span&gt;(&lt;span class=&quot;dv&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;at&quot;&gt;.class.mtimes&lt;/span&gt;&lt;span class=&quot;kw&quot;&gt;[&lt;/span&gt;path&lt;span class=&quot;kw&quot;&gt;]&lt;/span&gt;, &lt;span class=&quot;dv&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;at&quot;&gt;.class.mtimes&lt;/span&gt;&lt;span class=&quot;kw&quot;&gt;[&lt;/span&gt;path&lt;span class=&quot;kw&quot;&gt;]&lt;/span&gt;, dest_path)&lt;/span&gt;
&lt;span id=&quot;cb1-10&quot;&gt;&lt;a href=&quot;#cb1-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;cf&quot;&gt;end&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-11&quot;&gt;&lt;a href=&quot;#cb1-11&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;cf&quot;&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;As described in the &lt;a
href=&quot;https://ruby-doc.org/stdlib-1.9.3/libdoc/fileutils/rdoc/FileUtils.html&quot;&gt;docs
for FileUtils&lt;/a&gt;, &lt;code&gt;cp&lt;/code&gt; copies the file content, similarly to
&lt;code&gt;cp -L&lt;/code&gt;, while &lt;code&gt;copy_entry&lt;/code&gt; copies a link as a
link, like &lt;code&gt;cp -d&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;As the code implies, the behavior we want (&lt;code&gt;FileUtils.cp&lt;/code&gt;)
can be triggered by setting the environment to
&lt;code&gt;production&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;JEKYLL_ENV=production&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I don’t see why this shouldn’t be the default behavior, so I opened
an &lt;a href=&quot;https://github.com/jekyll/jekyll/issues/6870&quot;&gt;issue&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Interestingly, I’m pretty sure it used to work properly before. When
I discovered the issue, I rushed to check whether my site has been
broken all this time, but the files were in the right places on the
server. I thought that maybe this is a recent regression, but
&lt;code&gt;git blame&lt;/code&gt; says that this piece of code hasn’t changed in
years. I still have not solved this mystery.&lt;/p&gt;
&lt;h2 id=&quot;a-case-of-a-missing-file&quot;&gt;A case of a missing file&lt;/h2&gt;
&lt;p&gt;I needed to publish the files of a research project I’m working on.
The main code for the project is in an R markdown notebook (“Rmd”). I
was going to publish the raw &lt;code&gt;code.Rmd&lt;/code&gt; file, so that others
could run it, as well as its rendered version,
&lt;code&gt;code.html&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;When I looked into the &lt;code&gt;_site&lt;/code&gt; directory,
&lt;code&gt;code.html&lt;/code&gt; was there, but &lt;code&gt;code.Rmd&lt;/code&gt; was
mysteriously missing.&lt;/p&gt;
&lt;p&gt;It took me a while to find the problem, but it is a simple one: Rmd
is a markdown file with a YAML front matter — just like the markdown
files jekyll has to process. So the &lt;code&gt;code.html&lt;/code&gt; I was seeing
was not the original &lt;code&gt;code.html&lt;/code&gt; (which contains the output
of the R code) but the Rmd file rendered by jekyll. And like all the
other jekyll’s input files, &lt;code&gt;code.Rmd&lt;/code&gt; was not copied into
the output directory.&lt;/p&gt;
&lt;p&gt;This problem was discussed before (&lt;a
href=&quot;https://github.com/jekyll/jekyll/issues/77&quot;&gt;here&lt;/a&gt; and &lt;a
href=&quot;https://talk.jekyllrb.com/t/prevent-jekyll-from-processing-markdown-files-which-are-supposed-to-be-downloaded/1178&quot;&gt;here&lt;/a&gt;),
and the advice was to make jekyll ignore the problematic
files/directories and then use something else (like Gulp) to copy them
into the &lt;code&gt;_site&lt;/code&gt; directory.&lt;/p&gt;
&lt;p&gt;This seemed too complicated to me, so I made a small patch to support
“verbatim” directories, which are copied as is even if some of the files
contain the YAML front matter. To enable this, simply add&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb3&quot;&gt;&lt;pre
class=&quot;sourceCode yaml&quot;&gt;&lt;code class=&quot;sourceCode yaml&quot;&gt;&lt;span id=&quot;cb3-1&quot;&gt;&lt;a href=&quot;#cb3-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;fu&quot;&gt;verbatim&lt;/span&gt;&lt;span class=&quot;kw&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-2&quot;&gt;&lt;a href=&quot;#cb3-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;at&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;kw&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;at&quot;&gt; files&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;to your &lt;code&gt;_config.yml&lt;/code&gt;, where &lt;code&gt;files&lt;/code&gt; is the
name of the directory to copy verbatim.&lt;/p&gt;
&lt;p&gt;I submitted this feature as a &lt;a
href=&quot;https://github.com/jekyll/jekyll/pull/6871&quot;&gt;pull request&lt;/a&gt;,
which I hope will be accepted, but for the time being you can get it
from &lt;a href=&quot;https://github.com/UnkindPartition/jekyll&quot;&gt;my fork of the
jekyll repo&lt;/a&gt;.&lt;/p&gt;
</description>
                        <pubDate>Sat, 24 Mar 2018 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2018-03-24-jekyll</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2018-03-24-jekyll.html</guid>
                </item>
        
                <item>
                        <title>Export transactions from Santander</title>
                        <description>&lt;p&gt;Getting your transactions out of Santander’s online banking in a
machine readable format like csv is far from trivial.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/img/santander-export.png&quot; /&gt;&lt;/p&gt;
&lt;p&gt;At first this seems like a lot of options, but most of them are
useless:&lt;/p&gt;
&lt;p&gt;“Midata (csv)” gives a semicolon-separated(!) file with only three
transactions (out of 50+). It seems that these correspond to the two
deposits and one cash withdrawal I’ve had, but all the cashless payments
are absent. Additionally, the two deposits have their description masked
with asterisks.&lt;/p&gt;
&lt;p&gt;“Microsoft Excel (XLS)” indeed gives a file with an xls extension,
but that extension has nothing to do with the file’s contents.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% file 2018-03-03.xls
2018-03-03.xls: HTML document, ISO-8859 text, with very long lines&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It’s an html file consisting of a giant badly-formatted table,
littered with FONT tags.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/img/santander-xls-html.png&quot; /&gt;&lt;/p&gt;
&lt;p&gt;I thought that I could extract the data with &lt;a
href=&quot;https://cran.r-project.org/web/packages/htmltab/index.html&quot;&gt;htmltab&lt;/a&gt;,
but it only recognizes the date column, not sure why.&lt;/p&gt;
&lt;p&gt;Someone who goes by the name Infernus &lt;a
href=&quot;https://infernus.org/2016/01/27/fixing-santander-uk.html&quot;&gt;published
a Ruby script&lt;/a&gt; to extract the data from the html file. The script,
however, does not distinguish between the “money in” and “money out”
columns in the html table, and so a ₤100 deposit and a ₤100
payment/withdrawal look exactly the same in the output file.&lt;/p&gt;
&lt;p&gt;“Microsoft Money (QIF)” and “Intuit Quicken (QIF)” give exactly the
same file, and that file cannot be parsed with Finance::QIF and &lt;a
href=&quot;http://www.windley.com/archives/2009/08/converting_qif_files_to_csv.shtml&quot;&gt;this
script&lt;/a&gt;, resulting in an “Unknown header format” error.&lt;/p&gt;
&lt;p&gt;The only robust options to export the transactions seems to be
through their txt file format, which looks like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;From: 01/01/2018 to 03/03/2018
                            
Account: XXXX XXXX XXXX XXXX
                        
Date: 03/03/2018
Description: CARD PAYMENT TO STAGECOACH BUS,4.40 GBP, RATE 1.00/GBP ON 01-03-2018
Amount: -4.40   
Balance: XXXX

...&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;There are some peculiarities in the format, of course, like the
Latin1 encoding and the use of non-breaking spaces as a separator, but
all in all it can be easily parsed. Here’s a Perl script to convert
Santander’s text format to the tab-separated value format (tsv).&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb3&quot;&gt;&lt;pre
class=&quot;sourceCode perl&quot;&gt;&lt;code class=&quot;sourceCode perl&quot;&gt;&lt;span id=&quot;cb3-1&quot;&gt;&lt;a href=&quot;#cb3-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;#!/usr/bin/perl&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-2&quot;&gt;&lt;a href=&quot;#cb3-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-3&quot;&gt;&lt;a href=&quot;#cb3-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;fu&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;warnings&lt;/span&gt;;&lt;/span&gt;
&lt;span id=&quot;cb3-4&quot;&gt;&lt;a href=&quot;#cb3-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;fu&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;strict&lt;/span&gt;;&lt;/span&gt;
&lt;span id=&quot;cb3-5&quot;&gt;&lt;a href=&quot;#cb3-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-6&quot;&gt;&lt;a href=&quot;#cb3-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;co&quot;&gt;# The input file is encoded in iso-8859-1.&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-7&quot;&gt;&lt;a href=&quot;#cb3-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;fu&quot;&gt;open&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;my&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;$f&lt;/span&gt;, &lt;span class=&quot;ot&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;st&quot;&gt;&amp;lt;:encoding(iso-8859-1)&lt;/span&gt;&lt;span class=&quot;ot&quot;&gt;&amp;quot;&lt;/span&gt;, &lt;span class=&quot;wa&quot;&gt;$ARGV&lt;/span&gt;[&lt;span class=&quot;dv&quot;&gt;0&lt;/span&gt;]&lt;/span&gt;
&lt;span id=&quot;cb3-8&quot;&gt;&lt;a href=&quot;#cb3-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;ot&quot;&gt;or&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;die&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;qq{&lt;/span&gt;&lt;span class=&quot;st&quot;&gt;Could not open &lt;/span&gt;&lt;span class=&quot;wa&quot;&gt;$ARGV&lt;/span&gt;&lt;span class=&quot;st&quot;&gt;[0]: &lt;/span&gt;&lt;span class=&quot;wa&quot;&gt;$!&lt;/span&gt;&lt;span class=&quot;ot&quot;&gt;}&lt;/span&gt;;&lt;/span&gt;
&lt;span id=&quot;cb3-9&quot;&gt;&lt;a href=&quot;#cb3-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;fu&quot;&gt;binmode&lt;/span&gt;(STDOUT, &lt;span class=&quot;ot&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;st&quot;&gt;:utf8&lt;/span&gt;&lt;span class=&quot;ot&quot;&gt;&amp;quot;&lt;/span&gt;);&lt;/span&gt;
&lt;span id=&quot;cb3-10&quot;&gt;&lt;a href=&quot;#cb3-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-11&quot;&gt;&lt;a href=&quot;#cb3-11&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;co&quot;&gt;# Field and record separators.&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-12&quot;&gt;&lt;a href=&quot;#cb3-12&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;wa&quot;&gt;$,&lt;/span&gt; = &lt;span class=&quot;ot&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;ch&quot;&gt;\t&lt;/span&gt;&lt;span class=&quot;ot&quot;&gt;&amp;quot;&lt;/span&gt;;&lt;/span&gt;
&lt;span id=&quot;cb3-13&quot;&gt;&lt;a href=&quot;#cb3-13&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;wa&quot;&gt;$\&lt;/span&gt; = &lt;span class=&quot;ot&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;ch&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;ot&quot;&gt;&amp;quot;&lt;/span&gt;;&lt;/span&gt;
&lt;span id=&quot;cb3-14&quot;&gt;&lt;a href=&quot;#cb3-14&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-15&quot;&gt;&lt;a href=&quot;#cb3-15&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;co&quot;&gt;# Field names, for both the input and the output file.&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-16&quot;&gt;&lt;a href=&quot;#cb3-16&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;co&quot;&gt;# The order is arbitrary and determines the order of the&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-17&quot;&gt;&lt;a href=&quot;#cb3-17&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;co&quot;&gt;# columns in the output file.&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-18&quot;&gt;&lt;a href=&quot;#cb3-18&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;my&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;@names&lt;/span&gt; = &lt;span class=&quot;ot&quot;&gt;qw(&lt;/span&gt;Date Description Amount Balance&lt;span class=&quot;ot&quot;&gt;)&lt;/span&gt;;&lt;/span&gt;
&lt;span id=&quot;cb3-19&quot;&gt;&lt;a href=&quot;#cb3-19&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;co&quot;&gt;# Mapping from column names to column numbers.&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-20&quot;&gt;&lt;a href=&quot;#cb3-20&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;my&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;%pos&lt;/span&gt;;&lt;/span&gt;
&lt;span id=&quot;cb3-21&quot;&gt;&lt;a href=&quot;#cb3-21&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;dt&quot;&gt;@pos&lt;/span&gt;{&lt;span class=&quot;dt&quot;&gt;@names&lt;/span&gt;} = (&lt;span class=&quot;dv&quot;&gt;0&lt;/span&gt;..&lt;span class=&quot;dt&quot;&gt;$#names&lt;/span&gt;);&lt;/span&gt;
&lt;span id=&quot;cb3-22&quot;&gt;&lt;a href=&quot;#cb3-22&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-23&quot;&gt;&lt;a href=&quot;#cb3-23&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;co&quot;&gt;# Print the tsv header.&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-24&quot;&gt;&lt;a href=&quot;#cb3-24&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;fu&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;@names&lt;/span&gt;;&lt;/span&gt;
&lt;span id=&quot;cb3-25&quot;&gt;&lt;a href=&quot;#cb3-25&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-26&quot;&gt;&lt;a href=&quot;#cb3-26&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;my&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;@this&lt;/span&gt;;&lt;/span&gt;
&lt;span id=&quot;cb3-27&quot;&gt;&lt;a href=&quot;#cb3-27&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;while&lt;/span&gt; (&amp;lt;&lt;span class=&quot;dt&quot;&gt;$f&lt;/span&gt;&amp;gt;) {&lt;/span&gt;
&lt;span id=&quot;cb3-28&quot;&gt;&lt;a href=&quot;#cb3-28&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;if&lt;/span&gt; (&lt;span class=&quot;kw&quot;&gt;my&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;$name&lt;/span&gt;,&lt;span class=&quot;dt&quot;&gt;$value&lt;/span&gt;) = &lt;span class=&quot;ot&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;ch&quot;&gt;^(&lt;/span&gt;&lt;span class=&quot;bn&quot;&gt;\S&lt;/span&gt;&lt;span class=&quot;ch&quot;&gt;+)&lt;/span&gt;&lt;span class=&quot;ot&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;bn&quot;&gt;\s&lt;/span&gt;&lt;span class=&quot;ch&quot;&gt;*(&lt;/span&gt;&lt;span class=&quot;ot&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;ch&quot;&gt;*?)(&lt;/span&gt;&lt;span class=&quot;bn&quot;&gt;\s&lt;/span&gt;&lt;span class=&quot;ch&quot;&gt;*|&lt;/span&gt;&lt;span class=&quot;wa&quot;&gt;\x{A0}&lt;/span&gt;&lt;span class=&quot;ot&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;ch&quot;&gt;*)$&lt;/span&gt;&lt;span class=&quot;ot&quot;&gt;/g&lt;/span&gt;) {&lt;/span&gt;
&lt;span id=&quot;cb3-29&quot;&gt;&lt;a href=&quot;#cb3-29&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;kw&quot;&gt;if&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;$name&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;eq&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;Date&lt;/span&gt;&lt;span class=&quot;ot&quot;&gt;&amp;#39;&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;and&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;@this&lt;/span&gt;) {&lt;/span&gt;
&lt;span id=&quot;cb3-30&quot;&gt;&lt;a href=&quot;#cb3-30&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;fu&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;@this&lt;/span&gt;;&lt;/span&gt;
&lt;span id=&quot;cb3-31&quot;&gt;&lt;a href=&quot;#cb3-31&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;dt&quot;&gt;@this&lt;/span&gt; = ();&lt;/span&gt;
&lt;span id=&quot;cb3-32&quot;&gt;&lt;a href=&quot;#cb3-32&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    }&lt;/span&gt;
&lt;span id=&quot;cb3-33&quot;&gt;&lt;a href=&quot;#cb3-33&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;kw&quot;&gt;if&lt;/span&gt; (&lt;span class=&quot;fu&quot;&gt;defined&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;$pos&lt;/span&gt;{&lt;span class=&quot;dt&quot;&gt;$name&lt;/span&gt;}) {&lt;/span&gt;
&lt;span id=&quot;cb3-34&quot;&gt;&lt;a href=&quot;#cb3-34&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;dt&quot;&gt;$this&lt;/span&gt;[&lt;span class=&quot;dt&quot;&gt;$pos&lt;/span&gt;{&lt;span class=&quot;dt&quot;&gt;$name&lt;/span&gt;}] = &lt;span class=&quot;dt&quot;&gt;$value&lt;/span&gt;;&lt;/span&gt;
&lt;span id=&quot;cb3-35&quot;&gt;&lt;a href=&quot;#cb3-35&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    }&lt;/span&gt;
&lt;span id=&quot;cb3-36&quot;&gt;&lt;a href=&quot;#cb3-36&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  }&lt;/span&gt;
&lt;span id=&quot;cb3-37&quot;&gt;&lt;a href=&quot;#cb3-37&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;update-2018-06-05&quot;&gt;Update (2018-06-05)&lt;/h2&gt;
&lt;p&gt;The script is now updated to deal with an inconsistency in
Santander’s txt format. &lt;em&gt;Within the same file&lt;/em&gt;, I see some
records that include the currency&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Amount:&amp;lt;A0&amp;gt;-3.00&amp;lt;A0&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;and some that don’t&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Amount:&amp;lt;A0&amp;gt;-41.28&amp;lt;A0&amp;gt;GBP&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It’s scary to imagine how they generate this file.&lt;/p&gt;
</description>
                        <pubDate>Sun, 04 Mar 2018 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2018-03-04-santander-export-transactions</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2018-03-04-santander-export-transactions.html</guid>
                </item>
        
                <item>
                        <title>Undefined behavior with StablePtr in Haskell</title>
                        <description>&lt;p&gt;What will the following Haskell code snippet do?&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb1&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb1-1&quot;&gt;&lt;a href=&quot;#cb1-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  ptr1 &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; newStablePtr &lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-2&quot;&gt;&lt;a href=&quot;#cb1-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  ptr2 &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; newStablePtr &lt;span class=&quot;dv&quot;&gt;2&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-3&quot;&gt;&lt;a href=&quot;#cb1-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-4&quot;&gt;&lt;a href=&quot;#cb1-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;fu&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&amp;lt;&amp;lt;&lt;/span&gt; deRefStablePtr ptr1&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Of course it will print 1… most of the time. But it’s also easy to
make it print 2.&lt;/p&gt;
&lt;p&gt;Here is the full program:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb2&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb2-1&quot;&gt;&lt;a href=&quot;#cb2-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Foreign.StablePtr&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-2&quot;&gt;&lt;a href=&quot;#cb2-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-3&quot;&gt;&lt;a href=&quot;#cb2-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;main &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-4&quot;&gt;&lt;a href=&quot;#cb2-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  ptr &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; newStablePtr ()&lt;/span&gt;
&lt;span id=&quot;cb2-5&quot;&gt;&lt;a href=&quot;#cb2-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  freeStablePtr ptr&lt;/span&gt;
&lt;span id=&quot;cb2-6&quot;&gt;&lt;a href=&quot;#cb2-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  freeStablePtr ptr&lt;/span&gt;
&lt;span id=&quot;cb2-7&quot;&gt;&lt;a href=&quot;#cb2-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-8&quot;&gt;&lt;a href=&quot;#cb2-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  ptr1 &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; newStablePtr &lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-9&quot;&gt;&lt;a href=&quot;#cb2-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  ptr2 &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; newStablePtr &lt;span class=&quot;dv&quot;&gt;2&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-10&quot;&gt;&lt;a href=&quot;#cb2-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-11&quot;&gt;&lt;a href=&quot;#cb2-11&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;fu&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&amp;lt;&amp;lt;&lt;/span&gt; deRefStablePtr ptr1&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;If I compile it with ghc 8.0.2 on x86-64 Linux, it prints 2 and exits
cleanly. (Under ghci or runghc, it also prints 2 but then gets a
SIGBUS.) You can imagine how much fun it was to debug this issue in a
complex library with a non-obvious double free.&lt;/p&gt;
&lt;p&gt;The docs for &lt;code&gt;freeStablePtr&lt;/code&gt; say:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Dissolve the association between the stable pointer and the Haskell
value. Afterwards, if the stable pointer is passed to
&lt;code&gt;deRefStablePtr&lt;/code&gt; or &lt;code&gt;freeStablePtr&lt;/code&gt;, the behaviour
is undefined.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;As far as undefined behaviors go, this one is fairly benign — at
least it didn’t &lt;a
href=&quot;https://twitter.com/bos31337/status/116372971509121025&quot;&gt;delete my
code&lt;/a&gt; or install a backdoor.&lt;/p&gt;
&lt;p&gt;Let’s see what’s going on here. The relevant definitions are in
&lt;code&gt;includes/stg/Types.h&lt;/code&gt;, &lt;code&gt;includes/rts/Stable.h&lt;/code&gt;,
&lt;code&gt;rts/Stable.h&lt;/code&gt;, and &lt;code&gt;rts/Stable.c&lt;/code&gt;. The excerpts
below are simplified compared to the actual ghc source.&lt;/p&gt;
&lt;p&gt;A stable pointer is just an integer index into an array,
&lt;code&gt;stable_ptr_table&lt;/code&gt;, although it is represented as a
&lt;code&gt;void*&lt;/code&gt;.&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb3&quot;&gt;&lt;pre class=&quot;sourceCode c&quot;&gt;&lt;code class=&quot;sourceCode c&quot;&gt;&lt;span id=&quot;cb3-1&quot;&gt;&lt;a href=&quot;#cb3-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;co&quot;&gt;/*&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-2&quot;&gt;&lt;a href=&quot;#cb3-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;co&quot;&gt; * Stable Pointers: A stable pointer is represented as an index into&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-3&quot;&gt;&lt;a href=&quot;#cb3-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;co&quot;&gt; * the stable pointer table.&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-4&quot;&gt;&lt;a href=&quot;#cb3-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;co&quot;&gt; *&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-5&quot;&gt;&lt;a href=&quot;#cb3-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;co&quot;&gt; * StgStablePtr used to be a synonym for StgWord, but stable pointers&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-6&quot;&gt;&lt;a href=&quot;#cb3-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;co&quot;&gt; * are guaranteed to be void* on the C-side, so we have to do some&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-7&quot;&gt;&lt;a href=&quot;#cb3-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;co&quot;&gt; * occasional casting. Size is not a matter, because StgWord is always&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-8&quot;&gt;&lt;a href=&quot;#cb3-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;co&quot;&gt; * the same size as a void*.&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-9&quot;&gt;&lt;a href=&quot;#cb3-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;co&quot;&gt; */&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-10&quot;&gt;&lt;a href=&quot;#cb3-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-11&quot;&gt;&lt;a href=&quot;#cb3-11&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;typedef&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;*&lt;/span&gt; StgStablePtr&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-12&quot;&gt;&lt;a href=&quot;#cb3-12&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-13&quot;&gt;&lt;a href=&quot;#cb3-13&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;typedef&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-14&quot;&gt;&lt;a href=&quot;#cb3-14&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    StgPtr addr&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-15&quot;&gt;&lt;a href=&quot;#cb3-15&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;op&quot;&gt;}&lt;/span&gt; spEntry&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-16&quot;&gt;&lt;a href=&quot;#cb3-16&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-17&quot;&gt;&lt;a href=&quot;#cb3-17&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;spEntry &lt;span class=&quot;op&quot;&gt;*&lt;/span&gt;stable_ptr_table&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This is how the table works:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;If an index &lt;code&gt;i&lt;/code&gt; is allocated to a valid
&lt;code&gt;StablePtr&lt;/code&gt;, then &lt;code&gt;stable_ptr_table[i].addr&lt;/code&gt;
points to whatever heap object the stable pointer is supposed to point
to.&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb4&quot;&gt;&lt;pre
class=&quot;sourceCode c&quot;&gt;&lt;code class=&quot;sourceCode c&quot;&gt;&lt;span id=&quot;cb4-1&quot;&gt;&lt;a href=&quot;#cb4-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;StgPtr deRefStablePtr&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;StgStablePtr sp&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-2&quot;&gt;&lt;a href=&quot;#cb4-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-3&quot;&gt;&lt;a href=&quot;#cb4-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;cf&quot;&gt;return&lt;/span&gt; stable_ptr_table&lt;span class=&quot;op&quot;&gt;[(&lt;/span&gt;StgWord&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;sp&lt;span class=&quot;op&quot;&gt;].&lt;/span&gt;addr&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-4&quot;&gt;&lt;a href=&quot;#cb4-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If the index &lt;code&gt;i&lt;/code&gt; is free (not allocated to any valid
&lt;code&gt;StablePtr&lt;/code&gt;), then the corresponding entry in the table acts
as a node in a linked list that contains all free entries. The variable
&lt;code&gt;stable_ptr_free&lt;/code&gt; contains a pointer to the start of this
linked list.&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb5&quot;&gt;&lt;pre
class=&quot;sourceCode c&quot;&gt;&lt;code class=&quot;sourceCode c&quot;&gt;&lt;span id=&quot;cb5-1&quot;&gt;&lt;a href=&quot;#cb5-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;dt&quot;&gt;static&lt;/span&gt; spEntry &lt;span class=&quot;op&quot;&gt;*&lt;/span&gt;stable_ptr_free&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-2&quot;&gt;&lt;a href=&quot;#cb5-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-3&quot;&gt;&lt;a href=&quot;#cb5-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;co&quot;&gt;/* Free a StgStablePtr */&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-4&quot;&gt;&lt;a href=&quot;#cb5-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;dt&quot;&gt;void&lt;/span&gt; freeSpEntry&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;spEntry &lt;span class=&quot;op&quot;&gt;*&lt;/span&gt;sp&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-5&quot;&gt;&lt;a href=&quot;#cb5-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-6&quot;&gt;&lt;a href=&quot;#cb5-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    sp&lt;span class=&quot;op&quot;&gt;-&amp;gt;&lt;/span&gt;addr &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;P_&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;stable_ptr_free&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-7&quot;&gt;&lt;a href=&quot;#cb5-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    stable_ptr_free &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; sp&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-8&quot;&gt;&lt;a href=&quot;#cb5-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-9&quot;&gt;&lt;a href=&quot;#cb5-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-10&quot;&gt;&lt;a href=&quot;#cb5-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;co&quot;&gt;/* Allocate a fresh StgStablePtr */&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-11&quot;&gt;&lt;a href=&quot;#cb5-11&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;StgStablePtr getStablePtr&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;StgPtr p&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-12&quot;&gt;&lt;a href=&quot;#cb5-12&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-13&quot;&gt;&lt;a href=&quot;#cb5-13&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  StgWord sp&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-14&quot;&gt;&lt;a href=&quot;#cb5-14&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-15&quot;&gt;&lt;a href=&quot;#cb5-15&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  sp &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; stable_ptr_free &lt;span class=&quot;op&quot;&gt;-&lt;/span&gt; stable_ptr_table&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-16&quot;&gt;&lt;a href=&quot;#cb5-16&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  stable_ptr_free  &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;spEntry&lt;span class=&quot;op&quot;&gt;*)(&lt;/span&gt;stable_ptr_free&lt;span class=&quot;op&quot;&gt;-&amp;gt;&lt;/span&gt;addr&lt;span class=&quot;op&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-17&quot;&gt;&lt;a href=&quot;#cb5-17&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  stable_ptr_table&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;sp&lt;span class=&quot;op&quot;&gt;].&lt;/span&gt;addr &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; p&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-18&quot;&gt;&lt;a href=&quot;#cb5-18&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;cf&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;StgStablePtr&lt;span class=&quot;op&quot;&gt;)(&lt;/span&gt;sp&lt;span class=&quot;op&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-19&quot;&gt;&lt;a href=&quot;#cb5-19&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Suppose that the first two free entries in
&lt;code&gt;stable_ptr_table&lt;/code&gt; are 18 and 19, which is what I actually
observe at the program startup. (The RTS creates a few stable pointers
of its own for the purpose of running the program, which explains why
these don’t start at 0.) Here’s the double-free code annotated with what
happens on each step.&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb6&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb6-1&quot;&gt;&lt;a href=&quot;#cb6-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  ptr &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; newStablePtr ()&lt;/span&gt;
&lt;span id=&quot;cb6-2&quot;&gt;&lt;a href=&quot;#cb6-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;co&quot;&gt;-- ptr == 18&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-3&quot;&gt;&lt;a href=&quot;#cb6-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;co&quot;&gt;-- stable_ptr_free == &amp;amp;stable_ptr_table[19]&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-4&quot;&gt;&lt;a href=&quot;#cb6-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;co&quot;&gt;-- stable_ptr_table[18].addr is a pointer to a Haskell value ()&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-5&quot;&gt;&lt;a href=&quot;#cb6-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  freeStablePtr ptr&lt;/span&gt;
&lt;span id=&quot;cb6-6&quot;&gt;&lt;a href=&quot;#cb6-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;co&quot;&gt;-- stable_ptr_free == &amp;amp;stable_ptr_table[18]&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-7&quot;&gt;&lt;a href=&quot;#cb6-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;co&quot;&gt;-- stable_ptr_table[18].addr == &amp;amp;stable_ptr_table[19]&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-8&quot;&gt;&lt;a href=&quot;#cb6-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  freeStablePtr ptr&lt;/span&gt;
&lt;span id=&quot;cb6-9&quot;&gt;&lt;a href=&quot;#cb6-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;co&quot;&gt;-- stable_ptr_free == &amp;amp;stable_ptr_table[18]&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-10&quot;&gt;&lt;a href=&quot;#cb6-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;co&quot;&gt;-- stable_ptr_table[18].addr == &amp;amp;stable_ptr_table[18]&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-11&quot;&gt;&lt;a href=&quot;#cb6-11&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-12&quot;&gt;&lt;a href=&quot;#cb6-12&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  ptr1 &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; newStablePtr &lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-13&quot;&gt;&lt;a href=&quot;#cb6-13&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;co&quot;&gt;-- ptr1 == 18&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-14&quot;&gt;&lt;a href=&quot;#cb6-14&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;co&quot;&gt;-- stable_ptr_free == &amp;amp;stable_ptr_table[18]&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-15&quot;&gt;&lt;a href=&quot;#cb6-15&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;co&quot;&gt;-- stable_ptr_table[18].addr is a pointer to a Haskell value 1&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-16&quot;&gt;&lt;a href=&quot;#cb6-16&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  ptr2 &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; newStablePtr &lt;span class=&quot;dv&quot;&gt;2&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-17&quot;&gt;&lt;a href=&quot;#cb6-17&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;co&quot;&gt;-- ptr2 == 18&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-18&quot;&gt;&lt;a href=&quot;#cb6-18&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;co&quot;&gt;-- stable_ptr_free is a pointer to a Haskell value 1&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-19&quot;&gt;&lt;a href=&quot;#cb6-19&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;co&quot;&gt;-- stable_ptr_table[18].addr is a pointer to a Haskell value 2&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Because &lt;code&gt;stable_ptr_free&lt;/code&gt; now points into the Haskell heap
and outside of &lt;code&gt;stable_ptr_table&lt;/code&gt;, further allocations of
stable pointers will corrupt Haskell memory and eventually result in
SIGBUS or SIGSEGV.&lt;/p&gt;
</description>
                        <pubDate>Sat, 03 Feb 2018 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2018-02-03-stableptr-undefined-behavior</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2018-02-03-stableptr-undefined-behavior.html</guid>
                </item>
        
                <item>
                        <title>RPM packager&apos;s cheat sheet</title>
                        <description>&lt;p&gt;These are some random notes on creating RPM packages that I wrote
some time ago for my own use.&lt;/p&gt;
&lt;p&gt;I don’t have the time or motivation to organize them in a proper
article, but I thought I’d publish them anyway in case they are useful
to someone.&lt;/p&gt;
&lt;h2 id=&quot;the-rpm-build-tree&quot;&gt;The RPM build tree&lt;/h2&gt;
&lt;p&gt;On Fedora, the default rpm build tree is &lt;code&gt;~/rpmbuild&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ls ~/rpmbuild 
BUILD/
BUILDROOT/
RPMS/
SOURCES/
SPECS/
SRPMS/&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You can create this directory structure with
&lt;code&gt;rpmdev-setuptree&lt;/code&gt; from the &lt;code&gt;rpmdevtools&lt;/code&gt;
package.&lt;/p&gt;
&lt;p&gt;The purpose of each directory is:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;SPECS&lt;/code&gt;: spec files live here. They contain package
metainformation and build instructions. This is what you’ll be writing
when creating packages.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;SOURCES&lt;/code&gt;: download the source tarballs into this
directory.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;SRPMS&lt;/code&gt;: &lt;code&gt;.src.rpm&lt;/code&gt; bundle together a spec
file and the sources for that spec. You can create one with
&lt;code&gt;rpmbuild -bs&lt;/code&gt;, or download with
&lt;code&gt;dnf download   --source&lt;/code&gt;, and then build a binary package
from it with &lt;code&gt;rpmbuild -rb&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;BUILD&lt;/code&gt;: sources are unpacked into this directory and get
compiled here.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;BUILDROOT&lt;/code&gt;: during the install phase, files are copied
here.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;RPMS&lt;/code&gt;: the final rpms are created here.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;To change the location of the build tree, put this into
&lt;code&gt;~/.rpmmacros&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;%_topdir %{getenv:HOME}/myrpmbuild&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;srpms&quot;&gt;SRPMs&lt;/h2&gt;
&lt;p&gt;To customize a package that already exists in Fedora (for instance,
to update to a newer upstream version), it is convenient to download and
install an srpm (also known as src.rpm).&lt;/p&gt;
&lt;p&gt;First, download an srpm from &lt;a
href=&quot;https://dl.fedoraproject.org/pub/fedora/linux/releases/27/Everything/source/tree/Packages/&quot;&gt;dl.fedoraproject.org&lt;/a&gt;
(substitute your release number) to &lt;code&gt;~/rpmbuild/SRPMS&lt;/code&gt;.
Alternatively, use the program &lt;code&gt;yumdownloader&lt;/code&gt; from the
&lt;code&gt;dnf-utils&lt;/code&gt; package:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;yumdownloader --destdir ~/rpmbuild/SRPMS --source packagename&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Next, install it into your build tree:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;rpm -i ~/rpmbuild/SRPMS/packagename.src.rpm&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now the spec file should appear under &lt;code&gt;~/rpmbuild/SPECS&lt;/code&gt;
and sources under &lt;code&gt;~/rpmbuild/SOURCES&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&quot;rpm-macros&quot;&gt;RPM macros&lt;/h2&gt;
&lt;p&gt;Evaluate an RPM macro expression:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;rpm -E &amp;#39;%_topdir&amp;#39;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Show all macro definitions:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;rpm --showrc&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It will also show where the definitions are located: look for
something like
&lt;code&gt;Macro path: /usr/lib/rpm/macros:/usr/lib/rpm/macros.d/macros.*:/usr/lib/rpm/platform/%{_target}/macros:/usr/lib/rpm/fileattrs/*.attr:/usr/lib/rpm/redhat/macros:/etc/rpm/macros.*:/etc/rpm/macros:/etc/rpm/%{_target}/macros:~/.rpmmacros&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Unfortunately, it doesn’t seem to show where each particular macro
comes from.&lt;/p&gt;
&lt;h3 id=&quot;defining-your-own&quot;&gt;Defining your own&lt;/h3&gt;
&lt;p&gt;It’s often useful to define variables in the SPEC file.&lt;/p&gt;
&lt;p&gt;This can be done with either &lt;code&gt;%define&lt;/code&gt; or
&lt;code&gt;%global&lt;/code&gt;, and &lt;a
href=&quot;https://fedoraproject.org/wiki/PackagingDrafts/global_preferred_over_define&quot;&gt;&lt;code&gt;%global&lt;/code&gt;
is preferred&lt;/a&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;%define commit a0a746442daf8dfca01859f1efcc8663b47b3705
%global commit a0a746442daf8dfca01859f1efcc8663b47b3705&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;minimal-rpm-spec-file&quot;&gt;Minimal RPM spec file&lt;/h2&gt;
&lt;p&gt;I usually start with the minimal spec file:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Name:       minimal
Version:    1
Release:    1%{?dist}
Summary:    Minimal package
License:    MIT

%description
...

%prep

%build

%install

%files
/*&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;RPM has many defaults and convenient macros suited for traditional
&lt;code&gt;./configure &amp;amp;&amp;amp; make &amp;amp;&amp;amp; make install&lt;/code&gt;
tarballs, but nowadays those are actually rare.&lt;/p&gt;
&lt;h2 id=&quot;sources&quot;&gt;Sources&lt;/h2&gt;
&lt;p&gt;If you have any source files, they should be declared (usually above
&lt;code&gt;%description&lt;/code&gt;) like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;URL:        ftp://ftp.ncbi.nlm.nih.gov/entrez/entrezdirect/edirect.zip
Source0:    edirect.zip&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You can then download the sources automatically using
&lt;code&gt;spectool&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;spectool -C ~/rpmbuild/SOURCES -g package.spec&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Sometimes I don’t declare any sources and instead use a tool (such as
&lt;code&gt;pypi&lt;/code&gt; or &lt;code&gt;gem&lt;/code&gt;) to download and install the
software. This is not reproducible, and therefore unacceptable when
creating public packages, but is usually fine for personal use.&lt;/p&gt;
&lt;h3 id=&quot;github-sources&quot;&gt;github sources&lt;/h3&gt;
&lt;p&gt;Here’s an example of using a specific commit from a github repo.&lt;/p&gt;
&lt;p&gt;See also the pages on &lt;a
href=&quot;https://fedoraproject.org/wiki/Packaging:SourceURL?rd=Packaging/SourceURL#Git_Hosting_Services&quot;&gt;SourceURL
for git&lt;/a&gt; and &lt;a
href=&quot;https://fedoraproject.org/wiki/Packaging:Versioning#Snapshot_packages&quot;&gt;versioning
snapshots&lt;/a&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;%global   commit a0a746442daf8dfca01859f1efcc8663b47b3705
%global   shortcommit %(c=%{commit}; echo ${c:0:7})
Release:  1.%{shortcommit}
Source0:  https://github.com/lwindolf/%{name}/archive/%{commit}/%{name}-%{commit}.tar.gz

%prep
%setup -n %{name}-%{commit}&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;build-stages&quot;&gt;Build stages&lt;/h2&gt;
&lt;h3 id=&quot;prep&quot;&gt;%prep&lt;/h3&gt;
&lt;p&gt;At this stage, you unpack the source tarballs and apply patches. If
you have any sources to unpack, try to find a &lt;code&gt;%setup&lt;/code&gt;
invocation that does the trick. The flags to &lt;code&gt;%setup&lt;/code&gt; are
described elsewhere.&lt;/p&gt;
&lt;h2 id=&quot;auto-provides&quot;&gt;Auto-provides&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;http://stackoverflow.com/a/39819960/110081&quot;
class=&quot;uri&quot;&gt;http://stackoverflow.com/a/39819960/110081&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&quot;disable-debuginfo&quot;&gt;Disable debuginfo&lt;/h2&gt;
&lt;p&gt;Put this in the spec file:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;%global debug_package %{nil}&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;extract-dependencies-from-a-spec-file-and-install-them&quot;&gt;Extract
dependencies from a spec file and install them&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;dnf builddep package.spec&lt;/code&gt;&lt;/pre&gt;
</description>
                        <pubDate>Thu, 25 Jan 2018 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2018-01-25-rpm-packager-cheat-sheet</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2018-01-25-rpm-packager-cheat-sheet.html</guid>
                </item>
        
                <item>
                        <title>Asymmetry of costs in (t-)SNE</title>
                        <description>&lt;p&gt;Both the &lt;a
href=&quot;https://www.cs.toronto.edu/~fritz/absps/sne.pdf&quot;&gt;SNE&lt;/a&gt; and &lt;a
href=&quot;http://www.jmlr.org/papers/volume9/vandermaaten08a/vandermaaten08a.pdf&quot;&gt;t-SNE&lt;/a&gt;
papers contain the following claim:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Because the Kullback-Leibler divergence is not symmetric, different
types of error in the pairwise distances in the low-dimensional map are
not weighted equally. In particular, there is a large cost for using
widely separated map points to represent nearby datapoints (i.e., for
using a small &lt;span class=&quot;math inline&quot;&gt;\(q_{j|i}\)&lt;/span&gt; to model a
large &lt;span class=&quot;math inline&quot;&gt;\(p_{j|i}\)&lt;/span&gt;), but there is only a
small cost for using nearby map points to represent widely separated
datapoints.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;(t-SNE)&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Notice that making &lt;span class=&quot;math inline&quot;&gt;\(q_{ij}\)&lt;/span&gt; large
when &lt;span class=&quot;math inline&quot;&gt;\(p_{ij}\)&lt;/span&gt; is small wastes some of
the probability mass in the &lt;span class=&quot;math inline&quot;&gt;\(q\)&lt;/span&gt;
distribution so there is a cost for modeling a big distance in the
high-dimensional space with a small distance in the low-dimensional
space, though it is less than the cost of modeling a small distance with
a big one.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;(SNE)&lt;/p&gt;
&lt;p&gt;Here &lt;span class=&quot;math inline&quot;&gt;\(p_{ij}\)&lt;/span&gt; and &lt;span
class=&quot;math inline&quot;&gt;\(q_{ij}\)&lt;/span&gt; refer to the probabilities&lt;a
href=&quot;#fn1&quot; class=&quot;footnote-ref&quot; id=&quot;fnref1&quot;
role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;1&lt;/sup&gt;&lt;/a&gt; in the Kullback–Leibler cost
function&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;math display&quot;&gt;\[
KL(P||Q)=\sum_{i,j} p_{ij} \log\frac{p_{ij}}{q_{ij}},
\]&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;which are also measures of similarity: &lt;span
class=&quot;math inline&quot;&gt;\(p_{ij}\)&lt;/span&gt; is high when the points &lt;span
class=&quot;math inline&quot;&gt;\(i\)&lt;/span&gt; and &lt;span
class=&quot;math inline&quot;&gt;\(j\)&lt;/span&gt; are close to each other in the
original, high-dimensional space, and &lt;span
class=&quot;math inline&quot;&gt;\(q_{ij}\)&lt;/span&gt; is high when the points are close
in the low-dimensional map space.&lt;/p&gt;
&lt;p&gt;This got me thinking:&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;How do we interpret this claim?&lt;/li&gt;
&lt;li&gt;Does it hold universally as a mathematical theorem, or is it an
empirical observation that holds most of the time?&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;There is a simple but weak interpretation of the claim that obviously
holds. If &lt;span class=&quot;math inline&quot;&gt;\(q_{ij}\)&lt;/span&gt; tends to 0 (so the
points in the low-dimensional space become arbitrarily far apart), the
cost function tends to infinity, whereas if &lt;span
class=&quot;math inline&quot;&gt;\(p_{ij}\)&lt;/span&gt; tends to 0, the cost function
remains bounded. This interpretation is weak because it only applies
asymptotically, whereas in real (t-)SNE we are concerned with
distributions of points within small rectangular plots.&lt;/p&gt;
&lt;p&gt;Interpreting the claim is not trivial because we need two different
datasets:&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;A dataset where two close points are mapped to two points that are
farther away (high &lt;span class=&quot;math inline&quot;&gt;\(p\)&lt;/span&gt;, low &lt;span
class=&quot;math inline&quot;&gt;\(q\)&lt;/span&gt;), and&lt;/li&gt;
&lt;li&gt;a dataset where two distant points are mapped to two points that are
close (low &lt;span class=&quot;math inline&quot;&gt;\(p\)&lt;/span&gt;, high &lt;span
class=&quot;math inline&quot;&gt;\(q\)&lt;/span&gt;).&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Then the claim is that the value of the cost function in (1) is
higher than in (2). Clearly, the claim will not hold in general without
requiring some sort of relationship between the datasets (1) and
(2).&lt;/p&gt;
&lt;p&gt;This is a good time to introduce some simplifying assumptions:&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;The conditional probability distributions will be Gaussian, as in
the original SNE.&lt;/li&gt;
&lt;li&gt;We shall ignore the perplexity-based adaptive computation of the
variance in the data space and assume &lt;span
class=&quot;math inline&quot;&gt;\(\sigma^2=1/2\)&lt;/span&gt; instead, just like in the
map space. This makes &lt;span class=&quot;math inline&quot;&gt;\(p_{ij}\)&lt;/span&gt;
symmetric and easy to compute.&lt;/li&gt;
&lt;li&gt;Our original (“high-dimensional”) and map (“low-dimensional”) space
will both have dimension 2. This allows us to draw them easily and makes
it trivial to find the optimal embedding: take &lt;span
class=&quot;math inline&quot;&gt;\(y_i=x_i\)&lt;/span&gt;.&lt;/li&gt;
&lt;li&gt;Finally, our dataset will contain 3 points. We cannot work with only
2 points, because then &lt;span class=&quot;math inline&quot;&gt;\(p_{12}\)&lt;/span&gt; and
&lt;span class=&quot;math inline&quot;&gt;\(q_{12}\)&lt;/span&gt; will always be 1. But 3
points are enough to make SNE interesting and test the claim. We will
arrange these points to form isosceles triangles, where we fix the base
and move the apex towards or away from the base. The length of the base
will be 1, and the length of the legs will be denoted by &lt;span
class=&quot;math inline&quot;&gt;\(d\)&lt;/span&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;img src=&quot;/img/t-sne/fig1.svg&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Given these constraints, is it true that when we move &lt;span
class=&quot;math inline&quot;&gt;\(x_3\)&lt;/span&gt; closer to &lt;span
class=&quot;math inline&quot;&gt;\(x_1\)&lt;/span&gt; and &lt;span
class=&quot;math inline&quot;&gt;\(x_2\)&lt;/span&gt;, we suffer more than if we move it
away? Again, this has no hope to hold in general (for every combination
of left and right displacements): because the cost function is
continuous, for every given displacement to the left there is a
displacement to the right with a lower cost.&lt;/p&gt;
&lt;p&gt;What if we displace &lt;span class=&quot;math inline&quot;&gt;\(x_3\)&lt;/span&gt; to the
left and to the right by the same amount? Then the result would depend
on the specifics of the conditional distributions (normal, Cauchy) and
their parameters (&lt;span class=&quot;math inline&quot;&gt;\(\sigma\)&lt;/span&gt;), which we
are not modelling faithfully here, and would not be a result of the
asymmetry of the KL divergence as implied by the statements quoted
above.&lt;/p&gt;
&lt;p&gt;Motivated by these thoughts, I came up with an interpretation that
focuses solely on the asymmetry of the KL divergence, although it still
uses the Gaussian distribution to calculate &lt;span
class=&quot;math inline&quot;&gt;\(p_{ij}\)&lt;/span&gt; and &lt;span
class=&quot;math inline&quot;&gt;\(q_{ij}\)&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;In this interpretation, we consider two isosceles triangles with the
same base but different legs, &lt;span class=&quot;math inline&quot;&gt;\(d_1\)&lt;/span&gt;
and &lt;span class=&quot;math inline&quot;&gt;\(d_2\)&lt;/span&gt;. These triangles define
probability distributions &lt;span class=&quot;math inline&quot;&gt;\(P(d_1)\)&lt;/span&gt;
and &lt;span class=&quot;math inline&quot;&gt;\(P(d_2)\)&lt;/span&gt;. The asymmetry of the KL
divergence means that &lt;span
class=&quot;math inline&quot;&gt;\(KL(P(d_1)||P(d_2))\)&lt;/span&gt; and &lt;span
class=&quot;math inline&quot;&gt;\(KL(P(d_2)||P(d_1))\)&lt;/span&gt; are, in general,
different. These divergences arise when mapping the longer triangle onto
the shorter one and vice versa.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/img/t-sne/fig2.svg&quot; /&gt;&lt;/p&gt;
&lt;p&gt;So the question becomes: is it true that &lt;span
class=&quot;math inline&quot;&gt;\(d_1&amp;gt;d_2\)&lt;/span&gt; implies &lt;span
class=&quot;math inline&quot;&gt;\(KL(P(d_2)||P(d_1)) &amp;gt;
KL(P(d_1)||P(d_2))\)&lt;/span&gt;?&lt;/p&gt;
&lt;p&gt;This answer can be easily computed for different values of &lt;span
class=&quot;math inline&quot;&gt;\(d_1\)&lt;/span&gt; and &lt;span
class=&quot;math inline&quot;&gt;\(d_2\)&lt;/span&gt; in R:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb1&quot;&gt;&lt;pre class=&quot;sourceCode r&quot;&gt;&lt;code class=&quot;sourceCode r&quot;&gt;&lt;span id=&quot;cb1-1&quot;&gt;&lt;a href=&quot;#cb1-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;fu&quot;&gt;library&lt;/span&gt;(dplyr)&lt;/span&gt;
&lt;span id=&quot;cb1-2&quot;&gt;&lt;a href=&quot;#cb1-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;fu&quot;&gt;library&lt;/span&gt;(ggplot2)&lt;/span&gt;
&lt;span id=&quot;cb1-3&quot;&gt;&lt;a href=&quot;#cb1-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-4&quot;&gt;&lt;a href=&quot;#cb1-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;probs &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;cf&quot;&gt;function&lt;/span&gt;(d) {&lt;/span&gt;
&lt;span id=&quot;cb1-5&quot;&gt;&lt;a href=&quot;#cb1-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  p &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;exp&lt;/span&gt;(&lt;span class=&quot;sc&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;c&lt;/span&gt;(&lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;,d,d)&lt;span class=&quot;sc&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;2&lt;/span&gt;)&lt;/span&gt;
&lt;span id=&quot;cb1-6&quot;&gt;&lt;a href=&quot;#cb1-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;fu&quot;&gt;return&lt;/span&gt;(p&lt;span class=&quot;sc&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;sum&lt;/span&gt;(p))&lt;/span&gt;
&lt;span id=&quot;cb1-7&quot;&gt;&lt;a href=&quot;#cb1-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;}&lt;/span&gt;
&lt;span id=&quot;cb1-8&quot;&gt;&lt;a href=&quot;#cb1-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-9&quot;&gt;&lt;a href=&quot;#cb1-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;kl &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;Vectorize&lt;/span&gt;(&lt;span class=&quot;cf&quot;&gt;function&lt;/span&gt;(d1, d2) {&lt;/span&gt;
&lt;span id=&quot;cb1-10&quot;&gt;&lt;a href=&quot;#cb1-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  p &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;probs&lt;/span&gt;(d1)&lt;/span&gt;
&lt;span id=&quot;cb1-11&quot;&gt;&lt;a href=&quot;#cb1-11&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  q &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;probs&lt;/span&gt;(d2)&lt;/span&gt;
&lt;span id=&quot;cb1-12&quot;&gt;&lt;a href=&quot;#cb1-12&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;fu&quot;&gt;return&lt;/span&gt;(&lt;span class=&quot;fu&quot;&gt;sum&lt;/span&gt;(p&lt;span class=&quot;sc&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;log&lt;/span&gt;(p&lt;span class=&quot;sc&quot;&gt;/&lt;/span&gt;q)))&lt;/span&gt;
&lt;span id=&quot;cb1-13&quot;&gt;&lt;a href=&quot;#cb1-13&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;})&lt;/span&gt;
&lt;span id=&quot;cb1-14&quot;&gt;&lt;a href=&quot;#cb1-14&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-15&quot;&gt;&lt;a href=&quot;#cb1-15&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;d &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;expand.grid&lt;/span&gt;(&lt;span class=&quot;at&quot;&gt;d1=&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;seq&lt;/span&gt;(&lt;span class=&quot;fl&quot;&gt;0.5&lt;/span&gt;,&lt;span class=&quot;dv&quot;&gt;3&lt;/span&gt;,&lt;span class=&quot;at&quot;&gt;by=&lt;/span&gt;&lt;span class=&quot;fl&quot;&gt;0.03&lt;/span&gt;), &lt;span class=&quot;at&quot;&gt;d2=&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;seq&lt;/span&gt;(&lt;span class=&quot;fl&quot;&gt;0.5&lt;/span&gt;,&lt;span class=&quot;dv&quot;&gt;3&lt;/span&gt;,&lt;span class=&quot;at&quot;&gt;by=&lt;/span&gt;&lt;span class=&quot;fl&quot;&gt;0.03&lt;/span&gt;)) &lt;span class=&quot;sc&quot;&gt;%&amp;gt;%&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-16&quot;&gt;&lt;a href=&quot;#cb1-16&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;fu&quot;&gt;filter&lt;/span&gt;(d1&lt;span class=&quot;sc&quot;&gt;&amp;gt;&lt;/span&gt;d2) &lt;span class=&quot;sc&quot;&gt;%&amp;gt;%&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-17&quot;&gt;&lt;a href=&quot;#cb1-17&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;fu&quot;&gt;mutate&lt;/span&gt;(&lt;span class=&quot;at&quot;&gt;claim=&lt;/span&gt;(&lt;span class=&quot;fu&quot;&gt;kl&lt;/span&gt;(d1,d2)&lt;span class=&quot;sc&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;kl&lt;/span&gt;(d2,d1)))&lt;/span&gt;
&lt;span id=&quot;cb1-18&quot;&gt;&lt;a href=&quot;#cb1-18&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-19&quot;&gt;&lt;a href=&quot;#cb1-19&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;fu&quot;&gt;ggplot&lt;/span&gt;(d) &lt;span class=&quot;sc&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;geom_point&lt;/span&gt;(&lt;span class=&quot;fu&quot;&gt;aes&lt;/span&gt;(d1,d2,&lt;span class=&quot;at&quot;&gt;color=&lt;/span&gt;claim),&lt;span class=&quot;at&quot;&gt;size=&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;) &lt;span class=&quot;sc&quot;&gt;+&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-20&quot;&gt;&lt;a href=&quot;#cb1-20&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;fu&quot;&gt;scale_color_manual&lt;/span&gt;(&lt;span class=&quot;at&quot;&gt;values=&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;c&lt;/span&gt;(&lt;span class=&quot;st&quot;&gt;&amp;quot;red&amp;quot;&lt;/span&gt;,&lt;span class=&quot;st&quot;&gt;&amp;quot;darkgreen&amp;quot;&lt;/span&gt;)) &lt;span class=&quot;sc&quot;&gt;+&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-21&quot;&gt;&lt;a href=&quot;#cb1-21&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;fu&quot;&gt;theme_bw&lt;/span&gt;() &lt;span class=&quot;sc&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;coord_fixed&lt;/span&gt;()&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;img src=&quot;/img/t-sne/plot.svg&quot; style=&quot;max-height: 500px;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;As can be seen from the graph, the claim holds when &lt;span
class=&quot;math inline&quot;&gt;\(d_1\)&lt;/span&gt; is high enough, consistent with the
asymptotic interpretation. But it does not hold universally.&lt;/p&gt;
&lt;section id=&quot;footnotes&quot; class=&quot;footnotes footnotes-end-of-document&quot;
role=&quot;doc-endnotes&quot;&gt;
&lt;hr /&gt;
&lt;ol&gt;
&lt;li id=&quot;fn1&quot;&gt;&lt;p&gt;This is the formulation taken in t-SNE and the one I
explore here. In the original SNE paper, the probabilities were
asymmetric, and the cost function was a sum of KL divergences of pairs
of conditional distributions.&lt;a href=&quot;#fnref1&quot; class=&quot;footnote-back&quot;
role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</description>
                        <pubDate>Tue, 23 Jan 2018 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2018-01-23-t-sne-cost</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2018-01-23-t-sne-cost.html</guid>
                </item>
        
                <item>
                        <title>New patterns in tasty</title>
                        <description>&lt;p&gt;When I wrote &lt;a
href=&quot;https://github.com/UnkindPartition/tasty&quot;&gt;tasty&lt;/a&gt; in 2013, I
borrowed the &lt;a
href=&quot;https://github.com/UnkindPartition/tasty/tree/core-0.12.0.1#patterns&quot;&gt;pattern
language&lt;/a&gt; and its implementation from &lt;a
href=&quot;https://github.com/batterseapower/test-framework&quot;&gt;test-framework&lt;/a&gt;.
I wasn’t fond of that pattern language, but it did the job most of the
time, and the task of coming up with a better alternative was
daunting.&lt;/p&gt;
&lt;p&gt;Over the years, however, the pattern language and implementation
received more feature requests and complaints than any other aspect of
tasty.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Mikhail Glushenkov &lt;a
href=&quot;https://github.com/UnkindPartition/tasty/issues/36&quot;&gt;wanted to run
all tests in a group except a selected few&lt;/a&gt;,
e.g. &lt;code&gt;--pattern &apos;test-group/**&apos; --ignore &apos;test-group/test-3&apos;&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Utku Demir &lt;a
href=&quot;https://github.com/UnkindPartition/tasty/issues/38#issuecomment-73977767&quot;&gt;wanted
to specify a list of tests to run&lt;/a&gt;, such as “A and B, but not C and
D”; Philipp Hausmann and Süleyman Özarslan requested something similar
in the same issue.&lt;/li&gt;
&lt;li&gt;Rob Stewart &lt;a
href=&quot;https://github.com/UnkindPartition/tasty/issues/130&quot;&gt;wanted a
pattern&lt;/a&gt; that would match &lt;code&gt;Bar&lt;/code&gt; but not
&lt;code&gt;FooBar&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Daniel Mendler &lt;a
href=&quot;https://github.com/UnkindPartition/tasty/issues/164&quot;&gt;reported&lt;/a&gt;
that patterns with slashes didn’t work because slashes have special
meaning in the patterns.&lt;/li&gt;
&lt;li&gt;Levent Erkök, whose package sbv has more than 30k tasty tests, &lt;a
href=&quot;https://github.com/UnkindPartition/tasty/issues/175&quot;&gt;was concerned
about the performance of pattern matching&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Allowing regular expressions in patterns would fulfill some (though
not all) of these requests. However, using a regular expression library
has its downsides. Carter Schonwald repeatedly complained to me that
regex-tdfa takes ages to compile. Simon Jakobi &lt;a
href=&quot;https://github.com/UnkindPartition/tasty/issues/195&quot;&gt;noted&lt;/a&gt;
that regex-tdfa brings along several transitive dependencies (including
parsec), which further increases compilation time, makes the package
more prone to breakages, and makes it harder for the maintainers of core
packages to use tasty.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Every time someone filed an issue about tasty patterns, I would say
something like “oh, this will be fixed once I get around to that issue
from 2013 about the new patterns”. But I still had no idea what that new
pattern language should look like.&lt;/p&gt;
&lt;p&gt;The new pattern language had to be expressive, containing at least
the boolean operators. It had to allow matching against the test name,
the name of any of the groups containing the test, or the full test
path, like &lt;code&gt;Foo/Bar/Baz&lt;/code&gt; for a test named &lt;code&gt;Baz&lt;/code&gt; in
the test group &lt;code&gt;Bar&lt;/code&gt;, which itself is contained in the
top-level group &lt;code&gt;Foo&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Finally, there was an issue of familiarity. Whatever ad-hoc DSL I
would come up with, I had to document thoroughly its syntax and
semantics, and then I had to convince tasty users to learn a new
language and read the docs every time they wanted to filter their tests.
(Not that the old patterns were particularly intuitive.)&lt;/p&gt;
&lt;p&gt;The insight came to me last summer while I was spending time with my
family and working remotely from a cabin in Poltava oblast, Ukraine. The
language I needed already existed and was relatively well-known. It’s
called AWK!&lt;/p&gt;
&lt;figure&gt;
&lt;img src=&quot;/img/poltava.jpg&quot; alt=&quot;My workspace in Poltava oblast&quot; /&gt;
&lt;figcaption aria-hidden=&quot;true&quot;&gt;My workspace in Poltava
oblast&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;In AWK, the variable&lt;a href=&quot;#fn1&quot; class=&quot;footnote-ref&quot; id=&quot;fnref1&quot;
role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;1&lt;/sup&gt;&lt;/a&gt; &lt;code&gt;$0&lt;/code&gt; refers to the
current line of input (called a “record”), and the variables
&lt;code&gt;$1&lt;/code&gt;, &lt;code&gt;$2&lt;/code&gt; etc. refer to the fields resulting from
splitting the record on the field separator (like a tab or a comma).&lt;/p&gt;
&lt;p&gt;The analogy with test names in tasty is straightforward:
&lt;code&gt;$0&lt;/code&gt; denotes the full path of the test, &lt;code&gt;$1&lt;/code&gt;
denotes the outermost test group name, &lt;code&gt;$2&lt;/code&gt; for the next
group name, and so on. The test’s own name is &lt;code&gt;$NF&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Then you can use these variables together with string, numeric, and
boolean operators. Some examples:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;$2 == &quot;Two&quot;&lt;/code&gt; — select the subgroup &lt;code&gt;Two&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;$2 == &quot;Two&quot; &amp;amp;&amp;amp; $3 == &quot;Three&quot;&lt;/code&gt; — select the test
or subgroup named &lt;code&gt;Three&lt;/code&gt; in the subgroup named
&lt;code&gt;Two&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;$2 == &quot;Two&quot; || $2 == &quot;Twenty-two&quot;&lt;/code&gt; — select two
subgroups&lt;/li&gt;
&lt;li&gt;&lt;code&gt;$0 !~ /skip/&lt;/code&gt; or &lt;code&gt;! /skip/&lt;/code&gt; — select tests
whose full names (including group names) do not contain the word
&lt;code&gt;skip&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;$NF !~ /skip/&lt;/code&gt; — select tests whose own names (but not
group names) do not contain the word &lt;code&gt;skip&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;$(NF-1) ~ /QuickCheck/&lt;/code&gt; — select tests whose immediate
parent group name contains &lt;code&gt;QuickCheck&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The list of all supported functions and operators can be found in the
&lt;a
href=&quot;https://github.com/UnkindPartition/tasty#patterns&quot;&gt;README&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;As a shortcut, if the &lt;code&gt;-p&lt;/code&gt;/&lt;code&gt;--pattern&lt;/code&gt; argument
consists of letters, digits, and characters, it is matched against the
full test path, so &lt;code&gt;-p foo&lt;/code&gt; is equivalent to
&lt;code&gt;-p /foo/&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The subset of AWK recognized by tasty contains only expressions (no
statements like loops or function definitions), no assignment operators,
and no variables except &lt;code&gt;NF&lt;/code&gt;. Other than that, the most
salient deviation is that pattern matching (as in
&lt;code&gt;$3 ~ /foo/&lt;/code&gt;) does not use regular expressions, for the
reasons stated above. Instead, a pattern match means a simple substring
search — an idea suggested by Levent Erkök. So &lt;code&gt;/foo/&lt;/code&gt; in
tasty means exactly the same as in AWK, while AWK’s &lt;code&gt;/foo+/&lt;/code&gt;
cannot be expressed.&lt;/p&gt;
&lt;p&gt;This allowed me to drop regex-tdfa as a dependency and significantly
speed up the compilation time. An installation of tasty-1.0 (the new
major release featuring AWK patterns) from scratch (a fresh cabal
sandbox) takes 24 seconds on my laptop&lt;a href=&quot;#fn2&quot;
class=&quot;footnote-ref&quot; id=&quot;fnref2&quot; role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;2&lt;/sup&gt;&lt;/a&gt;,
while an installation of tasty-0.12.0.1 (the previous version, which
depends on regex-tdfa) takes 2 minutes 43 seconds.&lt;/p&gt;
&lt;p&gt;The performance improved, too. I tried &lt;a
href=&quot;https://github.com/UnkindPartition/tasty/issues/175#issuecomment-312966218&quot;&gt;Levent’s
example&lt;/a&gt;, which runs 30k dummy tests (&lt;code&gt;j @?= j&lt;/code&gt;). When run
with &lt;code&gt;--quiet&lt;/code&gt; (so no time is wasted on output),
tasty-0.12.0.1 takes 0.3 seconds to run all tests and 0.6 seconds to run
a single test selected by a pattern (&lt;code&gt;-p 9_2729&lt;/code&gt;). The new
tasty-1.0 takes the same time without a pattern, and less than 0.1
seconds with a pattern (also &lt;code&gt;-p 9_2729&lt;/code&gt;, which is equivalent
to &lt;code&gt;$0 ~ /9_2729/&lt;/code&gt;). The overhead of pattern matching,
although it was pretty low already (0.3 seconds per 30k tests), became
much smaller — so that it is now outweighed by the benefit of running
fewer dummy tests. I haven’t done any performance optimization at all&lt;a
href=&quot;#fn3&quot; class=&quot;footnote-ref&quot; id=&quot;fnref3&quot;
role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;3&lt;/sup&gt;&lt;/a&gt;, so I don’t even know where the
speedup came from, exactly.&lt;/p&gt;
&lt;p&gt;Earlier I said that I dropped regex-tdfa as a dependency for tasty
and that regex-tdfa in turn depended on parsec; but didn’t I have to
retain parsec or a similar library to parse the AWK syntax? No! We
already have a perfectly fine parser combinators module in the base
library, &lt;a
href=&quot;https://hackage.haskell.org/package/base-4.10.1.0/docs/Text-ParserCombinators-ReadP.html&quot;&gt;Text.ParserCombinators.ReadP&lt;/a&gt;.
Its original purpose was to back the standard &lt;code&gt;Read&lt;/code&gt;
instances, but there is no reason it can’t be used for something more
fun.&lt;/p&gt;
&lt;p&gt;I did borrow one small module from megaparsec for parsing expressions
(&lt;a
href=&quot;https://hackage.haskell.org/package/megaparsec-6.4.0/docs/Text-Megaparsec-Expr.html&quot;&gt;Text.Megaparsec.Expr&lt;/a&gt;),
which I adapted to work with &lt;code&gt;ReadP&lt;/code&gt; and to parse ternary
operators. The expression parser originally comes from parsec, but Mark
Karpov did a great job refactoring it, so I recommend you read Mark’s
version instead. The expression parser is an ingenious algorithm
deserving a separate blog post.&lt;/p&gt;
&lt;p&gt;Enjoy the new tasty patterns!&lt;/p&gt;
&lt;section id=&quot;footnotes&quot; class=&quot;footnotes footnotes-end-of-document&quot;
role=&quot;doc-endnotes&quot;&gt;
&lt;hr /&gt;
&lt;ol&gt;
&lt;li id=&quot;fn1&quot;&gt;&lt;p&gt;Actually, unlike in Perl, in AWK &lt;code&gt;$0&lt;/code&gt; is an
expression: the operator &lt;code&gt;$&lt;/code&gt; applied to the number
&lt;code&gt;0&lt;/code&gt;. Instead of &lt;code&gt;$0&lt;/code&gt; you could write
&lt;code&gt;$(1-1)&lt;/code&gt;. The most practically relevant implication is that
you can write &lt;code&gt;$NF&lt;/code&gt; for the last field in the record,
&lt;code&gt;$(NF-1)&lt;/code&gt; for the second to last field and so on.&lt;a
href=&quot;#fnref1&quot; class=&quot;footnote-back&quot; role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li id=&quot;fn2&quot;&gt;&lt;p&gt;Intel(R) Core(TM) i7-6500U CPU @ 2.50GHz, 2 cores (4
virtual), SSD.&lt;a href=&quot;#fnref2&quot; class=&quot;footnote-back&quot;
role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li id=&quot;fn3&quot;&gt;&lt;p&gt;I had an idea to do partial evaluation of the
expression, so that the condition &lt;code&gt;$2 == &quot;X&quot;&lt;/code&gt; would prune the
whole test subgroup with name &lt;code&gt;$2 == &quot;Y&quot;&lt;/code&gt; without having to
consider each test individually. But after doing the measurement, I saw
that matching is already fast enough. and the extra complexity is not
justified.&lt;a href=&quot;#fnref3&quot; class=&quot;footnote-back&quot;
role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</description>
                        <pubDate>Mon, 08 Jan 2018 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2018-01-08-tasty-new-patterns</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2018-01-08-tasty-new-patterns.html</guid>
                </item>
        
                <item>
                        <title>Where did all my probability go?</title>
                        <description>&lt;p&gt;Let &lt;span class=&quot;math inline&quot;&gt;\(X\)&lt;/span&gt; be a one-dimensional
normal variable with mean 0 and standard deviation &lt;span
class=&quot;math inline&quot;&gt;\(\sigma\)&lt;/span&gt;. What is the limit of &lt;span
class=&quot;math inline&quot;&gt;\(P(X&amp;gt;a|\sigma)\)&lt;/span&gt; when &lt;span
class=&quot;math inline&quot;&gt;\(\sigma\)&lt;/span&gt; tends to infinity?&lt;/p&gt;
&lt;p&gt;We can compute the probability &lt;span
class=&quot;math inline&quot;&gt;\(P(X&amp;gt;a|\sigma)\)&lt;/span&gt; as an integral of the
normal density function:&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;math display&quot;&gt;\[
P(X&amp;gt;a|\sigma)=\int_{a}^{+\infty}\frac{1}{\sqrt{2\pi}\sigma}
e^{-x^2/2\sigma^2}dx.
\]&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;As &lt;span class=&quot;math inline&quot;&gt;\(\sigma\)&lt;/span&gt; goes to infinity,
&lt;span class=&quot;math inline&quot;&gt;\(\frac{1}{\sqrt{2\pi}\sigma}\)&lt;/span&gt; goes to
0, and &lt;span class=&quot;math inline&quot;&gt;\(e^{-x^2/2\sigma^2}\)&lt;/span&gt; goes to
1. Their product, therefore, goes to 0, and so&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;math display&quot;&gt;\[
\lim_{\sigma\to+\infty}P(X&amp;gt;a|\sigma)=
\int_{a}^{+\infty}\lim_{\sigma\to+\infty} \frac{1}{\sqrt{2\pi}\sigma}
e^{-x^2/2\sigma^2}dx
=0.
\]&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;But this does not make sense, does it? As the standard deviation
increases, the normal distribution becomes more spread out, and the
probability that &lt;span class=&quot;math inline&quot;&gt;\(X\)&lt;/span&gt; will exceed a
fixed threshold &lt;span class=&quot;math inline&quot;&gt;\(a\)&lt;/span&gt; should increase,
not fall down to 0.&lt;/p&gt;
&lt;p&gt;Indeed, the same argument could be used to “show” that the
probability &lt;span class=&quot;math inline&quot;&gt;\(P(X\leq
a|\sigma)\)&lt;/span&gt; also tends to 0 as &lt;span
class=&quot;math inline&quot;&gt;\(\sigma\)&lt;/span&gt; increases. So where does all the
probability go?&lt;/p&gt;
&lt;p&gt;The problem in our reasoning is swapping the integral and the limit
operations, i.e. equating&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;math display&quot;&gt;\[
\lim_{\sigma\to+\infty}\int_{a}^{+\infty} \frac{1}{\sqrt{2\pi}\sigma}
e^{-x^2/2\sigma^2}dx
\]&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;to&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;math display&quot;&gt;\[
\int_{a}^{+\infty}\lim_{\sigma\to+\infty} \frac{1}{\sqrt{2\pi}\sigma}
e^{-x^2/2\sigma^2}dx.
\]&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;But why exactly this is a problem requries a little digging.&lt;/p&gt;
&lt;h2 id=&quot;proper-integrals&quot;&gt;Proper integrals&lt;/h2&gt;
&lt;p&gt;We might suspect that the reason swapping the integral and the limit
didn’t work is that we are integrating over an infinite interval &lt;span
class=&quot;math inline&quot;&gt;\([a;+\infty)\)&lt;/span&gt;; i.e. that our integral is
&lt;em&gt;improper&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;One reason to think so is that we would be right to conclude that
&lt;span class=&quot;math display&quot;&gt;\[\lim_{\sigma\to+\infty} P(a\leq X\leq
b|\sigma) = 0,\]&lt;/span&gt; where the integration happens over a finite
interval &lt;span class=&quot;math inline&quot;&gt;\([a,b]\)&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;The improperness of the integral does play a role, as we shall see
below; but by itself, properness is neither necessary nor sufficient to
swap the integral and the limit.&lt;/p&gt;
&lt;p&gt;A. Ya. Dorogovtsev in his mathematical analysis textbook gives the
following example (section 13.2.3):&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;math display&quot;&gt;\[
f(x,y)=\frac1y\left(1-x^{1/y}\right)x^{1/y},
\]&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;where &lt;span class=&quot;math inline&quot;&gt;\(x\in[1/2,1]\)&lt;/span&gt; and &lt;span
class=&quot;math inline&quot;&gt;\(y\in(0,1]\)&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;For any given &lt;span class=&quot;math inline&quot;&gt;\(y\)&lt;/span&gt;, &lt;span
class=&quot;math inline&quot;&gt;\(f(\cdot,y):[1/2,1]\to\mathbb{R}\)&lt;/span&gt; is a
continuous function on a closed interval, so &lt;span
class=&quot;math inline&quot;&gt;\(\int_{1/2}^1 f(x,y)dx\)&lt;/span&gt; is proper. And yet,
it can be shown that&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;math display&quot;&gt;\[
\forall x\in[1/2,1]\; \lim_{y\to 0+} f(x,y) = 0
\]&lt;/span&gt; while &lt;span class=&quot;math display&quot;&gt;\[
\lim_{y\to 0+}\int_{1/2}^1 f(x,y)dx = 1/2.
\]&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Let’s look at the graph of &lt;span
class=&quot;math inline&quot;&gt;\(f(x,y)\)&lt;/span&gt; for different values of &lt;span
class=&quot;math inline&quot;&gt;\(y\)&lt;/span&gt; to see what’s going on.&lt;/p&gt;
&lt;figure&gt;
&lt;video src=&quot;/img/nonuniform-example-1.mp4&quot; autoplay loop muted&gt;
&lt;/video&gt;
&lt;figcaption&gt;
Graph of &lt;span class=&quot;math inline&quot;&gt;\(f(\cdot,y)\)&lt;/span&gt; for decreasing
values of &lt;span class=&quot;math inline&quot;&gt;\(y\)&lt;/span&gt;.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;On the one hand, at any given &lt;span class=&quot;math inline&quot;&gt;\(x\)&lt;/span&gt;,
&lt;span class=&quot;math inline&quot;&gt;\(f(x,y)\)&lt;/span&gt; tends to 0. (Look at how the
function value changes for a fixed &lt;span
class=&quot;math inline&quot;&gt;\(x\)&lt;/span&gt;, say, &lt;span
class=&quot;math inline&quot;&gt;\(x=0.8\)&lt;/span&gt; or &lt;span
class=&quot;math inline&quot;&gt;\(x=0.9\)&lt;/span&gt;. It may be less obvious that the
same is true for &lt;span class=&quot;math inline&quot;&gt;\(x=0.99\)&lt;/span&gt;; you’ll
have to trust that the trend continues or verify it analytically.)&lt;/p&gt;
&lt;p&gt;On the other hand, the function as a whole does not seem to converge
to 0. This is formalized by the notion of &lt;em&gt;uniform
convergence&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;We say that &lt;span class=&quot;math inline&quot;&gt;\(g(x,y)\)&lt;/span&gt; converges
&lt;em&gt;uniformly&lt;/em&gt; to &lt;span class=&quot;math inline&quot;&gt;\(g(x)\)&lt;/span&gt; when
&lt;span class=&quot;math inline&quot;&gt;\(y\to y_0\)&lt;/span&gt; iff the maximum vertical
distance between the graphs of &lt;span
class=&quot;math inline&quot;&gt;\(g(x,y)\)&lt;/span&gt; and &lt;span
class=&quot;math inline&quot;&gt;\(g(x)\)&lt;/span&gt;, i.e. &lt;span
class=&quot;math inline&quot;&gt;\(\sup_x |g(x,y)-g(x)|\)&lt;/span&gt;, goes to 0.&lt;/p&gt;
&lt;p&gt;Uniform convergence on &lt;span class=&quot;math inline&quot;&gt;\([a,b]\)&lt;/span&gt; is
sufficient (although not necessary) to replace &lt;span
class=&quot;math inline&quot;&gt;\(\lim_{y\to y_0}\int_a^b g(x,y)dx\)&lt;/span&gt; with
&lt;span class=&quot;math inline&quot;&gt;\(\int_a^b \lim_{y\to
y_0}g(x,y)dx\)&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;Clearly, our &lt;span class=&quot;math inline&quot;&gt;\(f(x,y)\)&lt;/span&gt; converges to
0 non-uniformly: not only does &lt;span class=&quot;math inline&quot;&gt;\(\sup_x
|f(x,y)|\)&lt;/span&gt; not tend to 0, it tends to infinity. Non-uniform
convergence allows a travelling wave. Such a wave can contribute to the
integral while escaping the point-wise convergence analysis (the
function converges at every point, but only after the wave has
passed).&lt;/p&gt;
&lt;h2 id=&quot;improper-integrals&quot;&gt;Improper integrals&lt;/h2&gt;
&lt;p&gt;Let’s revisit our first example, the limit &lt;span
class=&quot;math display&quot;&gt;\[
\lim_{\sigma\to+\infty}P(X&amp;gt;a|\sigma)dx =
\lim_{\sigma\to+\infty}\int_{a}^{+\infty} \frac{1}{\sqrt{2\pi}\sigma}
e^{-x^2/2\sigma^2}dx.
\]&lt;/span&gt;&lt;/p&gt;
&lt;figure&gt;
&lt;video src=&quot;/img/nonuniform-example-2.mp4&quot; autoplay loop muted&gt;
&lt;/video&gt;
&lt;figcaption&gt;
A piece of the right tail of a normal distribution, &lt;span
class=&quot;math inline&quot;&gt;\(P(X|\sigma)\)&lt;/span&gt;, for increasing values of
&lt;span class=&quot;math inline&quot;&gt;\(\sigma\)&lt;/span&gt;.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Here again there is a wave traveling to the right (and a symmetric
one traveling to the left, not shown here).&lt;/p&gt;
&lt;p&gt;Because the wave travels with a finite speed, we may suspect
non-uniform convergence: no matter how large &lt;span
class=&quot;math inline&quot;&gt;\(\sigma\)&lt;/span&gt; is, there are always distant
enough points at which the density will temporarily increase as &lt;span
class=&quot;math inline&quot;&gt;\(\sigma\)&lt;/span&gt; continues to increase.&lt;/p&gt;
&lt;p&gt;And yet, the height of the wave diminishes, and &lt;span
class=&quot;math inline&quot;&gt;\(\frac{1}{\sqrt{2\pi}\sigma}
e^{-x^2/2\sigma^2}\)&lt;/span&gt; does converge to 0 uniformly:&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;math display&quot;&gt;\[
\sup_x \left|\frac{1}{\sqrt{2\pi}\sigma} e^{-x^2/2\sigma^2}\right|=
\frac{1}{\sqrt{2\pi}\sigma}\to 0\quad (\sigma\to+\infty).
\]&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;The reason why this is not enough to bring the limit under the
integral is that here we are dealing with an improper integral. Improper
integrals are themselves limits; recall that the improper integral is
defined as&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;math display&quot;&gt;\[
\int_{a}^{+\infty} \frac{1}{\sqrt{2\pi}\sigma} e^{-x^2/2\sigma^2}dx =
\lim_{b\to+\infty}\int_{a}^{b} \frac{1}{\sqrt{2\pi}\sigma}
e^{-x^2/2\sigma^2}dx.
\]&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Before we get to bring &lt;span
class=&quot;math inline&quot;&gt;\(\lim_{\sigma\to+\infty}\)&lt;/span&gt; under &lt;span
class=&quot;math inline&quot;&gt;\(\int_a^b\)&lt;/span&gt;, we need to sneak it past &lt;span
class=&quot;math inline&quot;&gt;\(\lim_{b\to+\infty}\)&lt;/span&gt; first. For that, the
limit &lt;span class=&quot;math display&quot;&gt;\[\lim_{b\to+\infty}\int_{a}^{b}
\frac{1}{\sqrt{2\pi}\sigma} e^{-x^2/2\sigma^2}dx\]&lt;/span&gt; itself needs
to converge uniformly as a function of &lt;span
class=&quot;math inline&quot;&gt;\(\sigma\)&lt;/span&gt;; i.e. &lt;span
class=&quot;math display&quot;&gt;\[\sup_{\sigma} \left|\int_{b}^{+\infty}
\frac{1}{\sqrt{2\pi}\sigma} e^{-x^2/2\sigma^2}dx\right|\to 0\quad
(b\to+\infty).\]&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Look, this is the same quantity that we started with: because the
integral is a positive and increasing function of &lt;span
class=&quot;math inline&quot;&gt;\(\sigma\)&lt;/span&gt;,&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;math display&quot;&gt;\[
\begin{split}
\sup_{\sigma} \left|\int_{b}^{+\infty} \frac{1}{\sqrt{2\pi}\sigma}
e^{-x^2/2\sigma^2}dx\right|&amp;amp;=
\lim_{\sigma\to+\infty}\int_{b}^{+\infty} \frac{1}{\sqrt{2\pi}\sigma}
e^{-x^2/2\sigma^2}dx\\&amp;amp;=
\lim_{\sigma\to+\infty}P(X&amp;gt;b|\sigma).
\end{split}
\]&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;If we assume that &lt;span class=&quot;math inline&quot;&gt;\(\forall
b\:\lim_{\sigma\to+\infty}P(X&amp;gt;b|\sigma)=0\)&lt;/span&gt;, then the integral
converges uniformly, we can bring the limit under the integral, and
prove that indeed, &lt;span class=&quot;math inline&quot;&gt;\(\forall
a\:\lim_{\sigma\to+\infty}P(X&amp;gt;a|\sigma)=0\)&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;But there is no reason to believe that the limit is zero, and that
explains why our calculation yielding 0 was wrong: the integral does not
converge uniformly.&lt;/p&gt;
&lt;p&gt;The actual calculation of &lt;span
class=&quot;math inline&quot;&gt;\(\lim_{\sigma\to+\infty}P(X&amp;gt;a|\sigma)\)&lt;/span&gt;
is simple: because &lt;span class=&quot;math inline&quot;&gt;\(\forall
a&amp;gt;0\:\lim_{\sigma\to+\infty}P(-a\leq X\leq a|\sigma)=0\)&lt;/span&gt;
(thanks to uniform convergence!), all the probability mass goes to
infinity, and because of the symmetry, each tail gets a half of it;
so&lt;/p&gt;
&lt;p&gt;&lt;span
class=&quot;math display&quot;&gt;\[\lim_{\sigma\to+\infty}P(X&amp;gt;a|\sigma)=1/2.\]&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;But I thought it would be instructive to investigate why the naive
calculation did not work, so here we are.&lt;/p&gt;
</description>
                        <pubDate>Fri, 29 Dec 2017 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2017-12-29-where-did-my-probability-go</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2017-12-29-where-did-my-probability-go.html</guid>
                </item>
        
                <item>
                        <title>Bioinformatics events in Europe in 2018</title>
                        <description>&lt;p&gt;Here are some conferences and summer schools that will take place in
Europe in 2018 and may be of interest to fellow bioinformaticians.&lt;/p&gt;
&lt;p&gt;See also: &lt;a
href=&quot;/articles/2018-12-06-europe-bioinformatics-events-2019&quot;&gt;Bioinformatics
events in Europe in 2019&lt;/a&gt;.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;
Event
&lt;/th&gt;
&lt;th&gt;
Dates
&lt;/th&gt;
&lt;th&gt;
Location
&lt;/th&gt;
&lt;th&gt;
Early registration price
&lt;/th&gt;
&lt;th&gt;
Early registration deadline
&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;a href=&quot;http://www.festivalofgenomicslondon.com/&quot;&gt;Festival of Genomics
London&lt;/a&gt;
&lt;/td&gt;
&lt;td&gt;
January 30–31
&lt;/td&gt;
&lt;td&gt;
London, UK
&lt;/td&gt;
&lt;td&gt;
Free
&lt;/td&gt;
&lt;td&gt;
&lt;!--None?--&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;a
href=&quot;https://www.impan.pl/en/activities/banach-center/conferences/18-sstransmission&quot;&gt;Information
transmission in biological systems&lt;/a&gt;
&lt;/td&gt;
&lt;td&gt;
March 5–9
&lt;/td&gt;
&lt;td&gt;
Będlewo, Poland
&lt;/td&gt;
&lt;td&gt;
&lt;/td&gt;
&lt;td&gt;
February 10
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;a
href=&quot;https://coursesandconferences.wellcomegenomecampus.org/events/item.aspx?e=668&quot;&gt;Single
Cell Biology&lt;/a&gt;
&lt;/td&gt;
&lt;td&gt;
March 6–8
&lt;/td&gt;
&lt;td&gt;
Hinxton, UK
&lt;/td&gt;
&lt;td&gt;
₤229–429
&lt;/td&gt;
&lt;td&gt;
Novermber 28 (2017)
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;a
href=&quot;https://www.impan.pl/en/activities/banach-center/conferences/18-ssindividual&quot;&gt;From
individual based models to structured population level description&lt;/a&gt;
&lt;/td&gt;
&lt;td&gt;
March 12–16
&lt;/td&gt;
&lt;td&gt;
Będlewo, Poland
&lt;/td&gt;
&lt;td&gt;
€200
&lt;/td&gt;
&lt;td&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;a href=&quot;https://www.iscb.org/ngs2018&quot;&gt;NGS&lt;/a&gt;
&lt;/td&gt;
&lt;td&gt;
April 9–11
&lt;/td&gt;
&lt;td&gt;
Barcelona, Spain
&lt;/td&gt;
&lt;td&gt;
€125–395
&lt;/td&gt;
&lt;td&gt;
March 12
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;a href=&quot;http://recomb2018.fr/&quot;&gt;RECOMB&lt;/a&gt;
&lt;/td&gt;
&lt;td&gt;
April 21–24&lt;br&gt;Satellites: April 19–20
&lt;/td&gt;
&lt;td&gt;
Paris, France
&lt;/td&gt;
&lt;td&gt;
€135–700
&lt;/td&gt;
&lt;td&gt;
February 26
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;a href=&quot;http://dsb2018.cs.helsinki.fi/index.html&quot;&gt;Workshop on Data
Structures in Bioinformatics&lt;/a&gt;
&lt;/td&gt;
&lt;td&gt;
May 16–17
&lt;/td&gt;
&lt;td&gt;
Helsinki, Finland
&lt;/td&gt;
&lt;td&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;a href=&quot;http://quantitative-genomics.com/&quot;&gt;Quantitative Genomics&lt;/a&gt;
&lt;/td&gt;
&lt;td&gt;
June 14
&lt;/td&gt;
&lt;td&gt;
London, UK
&lt;/td&gt;
&lt;td&gt;
₤40
&lt;/td&gt;
&lt;td&gt;
March 31
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;a
href=&quot;https://www.iri-ls.hu-berlin.de/en/events/symposia/symposia&quot;&gt;From
Cells to Process: Advances and Challenges in Single Cell Biology&lt;/a&gt;
&lt;/td&gt;
&lt;td&gt;
June 28–29
&lt;/td&gt;
&lt;td&gt;
Berlin, Germany
&lt;/td&gt;
&lt;td&gt;
Free
&lt;/td&gt;
&lt;td&gt;
May 15
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;a href=&quot;http://www-huber.embl.de/csama2018/&quot;&gt;Statistical Data Analysis
for Genome Scale Biology&lt;/a&gt;
&lt;/td&gt;
&lt;td&gt;
July 8–13
&lt;/td&gt;
&lt;td&gt;
Brixen, Italy
&lt;/td&gt;
&lt;td&gt;
€850–2440
&lt;/td&gt;
&lt;td&gt;
May 15
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;a href=&quot;https://bio.liparischool.it/&quot;&gt;Computational Immunology,
Immunotherapy and Autoimmune Diseases Summer School&lt;/a&gt;
&lt;/td&gt;
&lt;td&gt;
July 25–31
&lt;/td&gt;
&lt;td&gt;
Lipari, Italy
&lt;/td&gt;
&lt;td&gt;
€500
&lt;/td&gt;
&lt;td&gt;
April 20
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;a
href=&quot;http://www.imprs-celldevosys.de/join/summer-school/introduction/&quot;&gt;Dresden
Summer School in Systems Biology&lt;/a&gt;
&lt;/td&gt;
&lt;td&gt;
August 11–18
&lt;/td&gt;
&lt;td&gt;
Dresden, Germany
&lt;/td&gt;
&lt;td&gt;
€100–500
&lt;/td&gt;
&lt;td&gt;
April 20
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;a href=&quot;http://evolutionmontpellier2018.org/&quot;&gt;Joint Congress on
Evolutionary Biology&lt;/a&gt;
&lt;/td&gt;
&lt;td&gt;
August 18–22
&lt;/td&gt;
&lt;td&gt;
Montpellier, France
&lt;/td&gt;
&lt;td&gt;
€100–500
&lt;/td&gt;
&lt;td&gt;
&lt;!--Not known yet--&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;a href=&quot;http://eccb18.org/&quot;&gt;European Conference on Computational
Biology&lt;/a&gt;
&lt;/td&gt;
&lt;td&gt;
September 8–12
&lt;/td&gt;
&lt;td&gt;
Athens, Greece
&lt;/td&gt;
&lt;td&gt;
€420–860
&lt;/td&gt;
&lt;td&gt;
July 31
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;a href=&quot;http://ngschool.eu/&quot;&gt;NGSchool&lt;/a&gt;
&lt;/td&gt;
&lt;td&gt;
September 16–23
&lt;/td&gt;
&lt;td&gt;
Lublin, Poland
&lt;/td&gt;
&lt;td&gt;
&lt;!--Not known yet--&gt;
&lt;/td&gt;
&lt;td&gt;
June 30
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;a
href=&quot;https://coursesandconferences.wellcomegenomecampus.org/events/item.aspx?e=731&quot;&gt;Genome
Informatics&lt;/a&gt;
&lt;/td&gt;
&lt;td&gt;
September 17–20
&lt;/td&gt;
&lt;td&gt;
Hinxton, UK
&lt;/td&gt;
&lt;td&gt;
₤320–520
&lt;/td&gt;
&lt;td&gt;
June 26
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;a href=&quot;http://rnabio.space/&quot;&gt;Single-cell RNABIO &amp;amp; organoids&lt;/a&gt;
&lt;/td&gt;
&lt;td&gt;
September 28–30
&lt;/td&gt;
&lt;td&gt;
Kyiv, Ukraine
&lt;/td&gt;
&lt;td&gt;
Free
&lt;/td&gt;
&lt;td&gt;
August 15
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;a href=&quot;http://gcb2018.de/&quot;&gt;German Conference on Bioinformatics&lt;/a&gt;
&lt;/td&gt;
&lt;td&gt;
September 25–28
&lt;/td&gt;
&lt;td&gt;
Vienna, Austria
&lt;/td&gt;
&lt;td&gt;
€400
&lt;/td&gt;
&lt;td&gt;
July 15
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;a
href=&quot;https://www.mdc-berlin.de/40850300/en/research/themes/bimsb/Events/Berlin-Summer-Meeting&quot;&gt;Grand
BIMSB Opening Symposium&lt;/a&gt;
&lt;/td&gt;
&lt;td&gt;
October 25–27
&lt;/td&gt;
&lt;td&gt;
Berlin, Germany
&lt;/td&gt;
&lt;td&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
</description>
                        <pubDate>Wed, 27 Dec 2017 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2017-12-27-europe-bioinformatics-events-2018</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2017-12-27-europe-bioinformatics-events-2018.html</guid>
                </item>
        
                <item>
                        <title>Explained variance in PCA</title>
                        <description>&lt;p&gt;There are quite a few explanations of the principal component
analysis (PCA) on the internet, some of them &lt;a
href=&quot;https://liorpachter.wordpress.com/2014/05/26/what-is-principal-component-analysis/&quot;&gt;quite
insightful&lt;/a&gt;. However, one issue that is usually skipped over is the
variance explained by principal components, as in “the first 5 PCs
explain 86% of variance”. So this is my attempt to explain the explained
variance.&lt;/p&gt;
&lt;h2 id=&quot;tldr&quot;&gt;TL;DR&lt;/h2&gt;
&lt;p&gt;The &lt;strong&gt;total variance&lt;/strong&gt; is the sum of variances of all
individual principal components.&lt;/p&gt;
&lt;p&gt;The fraction of &lt;strong&gt;variance explained&lt;/strong&gt; by a principal
component is the ratio between the variance of that principal component
and the total variance.&lt;/p&gt;
&lt;p&gt;For several principal components, add up their variances and divide
by the total variance.&lt;/p&gt;
&lt;h2 id=&quot;example-explanation&quot;&gt;Example &amp;amp; explanation&lt;/h2&gt;
&lt;p&gt;Let’s define a data set (matrix) in R that consists of 3 variables
(columns) and 4 observations (rows), where the third variable is roughly
the average of the first two.&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb1&quot;&gt;&lt;pre class=&quot;sourceCode r&quot;&gt;&lt;code class=&quot;sourceCode r&quot;&gt;&lt;span id=&quot;cb1-1&quot;&gt;&lt;a href=&quot;#cb1-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;fu&quot;&gt;set.seed&lt;/span&gt;(&lt;span class=&quot;dv&quot;&gt;2018&lt;/span&gt;)&lt;/span&gt;
&lt;span id=&quot;cb1-2&quot;&gt;&lt;a href=&quot;#cb1-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;mx &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;matrix&lt;/span&gt;(&lt;span class=&quot;fu&quot;&gt;rnorm&lt;/span&gt;(&lt;span class=&quot;dv&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;sc&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;2&lt;/span&gt;), &lt;span class=&quot;at&quot;&gt;nrow=&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;4&lt;/span&gt;, &lt;span class=&quot;at&quot;&gt;ncol=&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;2&lt;/span&gt;)&lt;/span&gt;
&lt;span id=&quot;cb1-3&quot;&gt;&lt;a href=&quot;#cb1-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;mx &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;cbind&lt;/span&gt;(mx, (mx[,&lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;]&lt;span class=&quot;sc&quot;&gt;+&lt;/span&gt;mx[,&lt;span class=&quot;dv&quot;&gt;2&lt;/span&gt;])&lt;span class=&quot;sc&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;sc&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;rnorm&lt;/span&gt;(&lt;span class=&quot;dv&quot;&gt;4&lt;/span&gt;, &lt;span class=&quot;at&quot;&gt;sd=&lt;/span&gt;&lt;span class=&quot;fl&quot;&gt;0.4&lt;/span&gt;))&lt;/span&gt;
&lt;span id=&quot;cb1-4&quot;&gt;&lt;a href=&quot;#cb1-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;mx&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;pre&gt;&lt;code&gt;            [,1]       [,2]       [,3]
[1,] -0.42298398  1.7352837  0.4119150
[2,] -1.54987816 -0.2647112 -0.6524724
[3,] -0.06442932  2.0994707  0.7603068
[4,]  0.27088135  0.8633512  0.1551048&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And let’s compute the sample variances of each of the 3 variables
(columns):&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb3&quot;&gt;&lt;pre class=&quot;sourceCode r&quot;&gt;&lt;code class=&quot;sourceCode r&quot;&gt;&lt;span id=&quot;cb3-1&quot;&gt;&lt;a href=&quot;#cb3-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;vars &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;apply&lt;/span&gt;(mx, &lt;span class=&quot;dv&quot;&gt;2&lt;/span&gt;, var)&lt;/span&gt;
&lt;span id=&quot;cb3-2&quot;&gt;&lt;a href=&quot;#cb3-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;vars&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;pre&gt;&lt;code&gt;[1] 0.6261715 1.1068959 0.3612204&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Note that these are different from true population variances, which
we know to be equal to 1, 1, and 0.66, respectively.&lt;/p&gt;
&lt;p&gt;When talking about PCA, the sum of the sample variances of all
individual variables is called the &lt;em&gt;total variance&lt;/em&gt;. If we divide
individual variances by the total variance, we’ll see how much variance
each variable explains:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb5&quot;&gt;&lt;pre class=&quot;sourceCode r&quot;&gt;&lt;code class=&quot;sourceCode r&quot;&gt;&lt;span id=&quot;cb5-1&quot;&gt;&lt;a href=&quot;#cb5-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;vars&lt;span class=&quot;sc&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;sum&lt;/span&gt;(vars)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;pre&gt;&lt;code&gt;[1] 0.2989902 0.5285309 0.1724789&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The highest fraction of explained variance among these variables is
53%, and the lowest one is 17%. We can also compute these fractions for
subsets of variables. For instance, variables 1 and 2 together explain
83% of the total variance, and variables 1 and 3 explain 47%.&lt;/p&gt;
&lt;p&gt;Principal component analysis computes a new set of variables
(“principal components”) and expresses the data in terms of these new
variables. Considered together, the new variables represent the same
amount of information as the original variables, in the sense that we
can restore the original data set from the transformed one.&lt;/p&gt;
&lt;p&gt;Moreover, the total variance remains the same. However, it is
redistributed among the new variables in the most “unequal” way: the
first variable not only explains the most variance among the new
variables, but the most variance a single variable can possibly
explain.&lt;/p&gt;
&lt;p&gt;More generally, the first &lt;span class=&quot;math inline&quot;&gt;\(k\)&lt;/span&gt;
principal components (where &lt;span class=&quot;math inline&quot;&gt;\(k\)&lt;/span&gt; can
be 1, 2, 3 etc.) explain the most variance any &lt;span
class=&quot;math inline&quot;&gt;\(k\)&lt;/span&gt; variables can explain, and the last
&lt;span class=&quot;math inline&quot;&gt;\(k\)&lt;/span&gt; variables explain the least
variance any &lt;span class=&quot;math inline&quot;&gt;\(k\)&lt;/span&gt; variables can
explain, under some general restrictions. (The restrictions ensure, for
example, that we cannot adjust a variable’s explained variance simply by
scaling it.)&lt;/p&gt;
&lt;p&gt;Let’s try this in practice. This is our data set expressed in the new
variables (“principal components”) called PC1, PC2, and PC3:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb7&quot;&gt;&lt;pre class=&quot;sourceCode r&quot;&gt;&lt;code class=&quot;sourceCode r&quot;&gt;&lt;span id=&quot;cb7-1&quot;&gt;&lt;a href=&quot;#cb7-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;pca &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;prcomp&lt;/span&gt;(mx, &lt;span class=&quot;at&quot;&gt;retx=&lt;/span&gt;T)&lt;/span&gt;
&lt;span id=&quot;cb7-2&quot;&gt;&lt;a href=&quot;#cb7-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;mx_transformed &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; pca&lt;span class=&quot;sc&quot;&gt;$&lt;/span&gt;x&lt;/span&gt;
&lt;span id=&quot;cb7-3&quot;&gt;&lt;a href=&quot;#cb7-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;mx_transformed&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;pre&gt;&lt;code&gt;            PC1        PC2          PC3
[1,] -0.5876362 -0.3227198  0.055468818
[2,]  1.9378229 -0.1805488 -0.012606347
[3,] -1.1907211 -0.2331953 -0.048668119
[4,] -0.1594657  0.7364640  0.005805649&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;These are the sample variances of the new variables.&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb9&quot;&gt;&lt;pre class=&quot;sourceCode r&quot;&gt;&lt;code class=&quot;sourceCode r&quot;&gt;&lt;span id=&quot;cb9-1&quot;&gt;&lt;a href=&quot;#cb9-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;vars_transformed &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;apply&lt;/span&gt;(mx_transformed, &lt;span class=&quot;dv&quot;&gt;2&lt;/span&gt;, var)&lt;/span&gt;
&lt;span id=&quot;cb9-2&quot;&gt;&lt;a href=&quot;#cb9-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;co&quot;&gt;# or: pca$sdev^2&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb9-3&quot;&gt;&lt;a href=&quot;#cb9-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;vars_transformed&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;pre&gt;&lt;code&gt;        PC1         PC2         PC3 
1.847906652 0.244501735 0.001879334 &lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Notice that their sum, the total variance, is the same as for the
original variables: 2.09.&lt;/p&gt;
&lt;p&gt;And these are the same variances divided by the total variance,
i.e. how much of the total variance each new variable explains:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb11&quot;&gt;&lt;pre class=&quot;sourceCode r&quot;&gt;&lt;code class=&quot;sourceCode r&quot;&gt;&lt;span id=&quot;cb11-1&quot;&gt;&lt;a href=&quot;#cb11-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;vars_transformed&lt;span class=&quot;sc&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;sum&lt;/span&gt;(vars_transformed)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;pre&gt;&lt;code&gt;         PC1          PC2          PC3 
0.8823556734 0.1167469648 0.0008973618 &lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In the original data set, the highest explained variance by a single
variable was 53%; here it’s 88%. And the lowest explained variance
dropped from 17% to less than 0.1%. The highest explained variance by
two variables also increased, from 83% to 99.9%, and so on. (Because the
total variance has not changed, these observation about the fractions of
the total variance are equally valid for the variances themselves.)&lt;/p&gt;
&lt;p&gt;Caution: PCA, being derived from noisy data, is itself noisy. For
instance, it would be a mistake to conclude that there exists a
parameter that explains 88% of the variability in the actual quantities
we have measured. The true fraction of total variance that can be
captured by a single variable in this case is only around 60%, and we
would get closer to it if we increased our sample size.&lt;/p&gt;
&lt;h2 id=&quot;mathematical-justification&quot;&gt;Mathematical justification&lt;/h2&gt;
&lt;p&gt;Hopefully the above explanation makes an intuitive sense. But, from a
mathematical perspective, it raises several questions:&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;What does it mean to introduce new variables?&lt;/li&gt;
&lt;li&gt;Why is the total variance preserved?&lt;/li&gt;
&lt;li&gt;Why can’t we make the variance for individual variables as low or
high as we want simply by scaling them?&lt;/li&gt;
&lt;li&gt;Why is it desirable to maximize explained variance?&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Let &lt;span class=&quot;math inline&quot;&gt;\(X\)&lt;/span&gt; be an &lt;span
class=&quot;math inline&quot;&gt;\(n\times p\)&lt;/span&gt; matrix whose columns correspond
to &lt;span class=&quot;math inline&quot;&gt;\(p\)&lt;/span&gt; variables and whose rows
correspond to &lt;span class=&quot;math inline&quot;&gt;\(n\)&lt;/span&gt; samples or
measurements.&lt;/p&gt;
&lt;p&gt;What does it mean to introduce new variables? In a very general
sense, it means coming up with a mapping (mathematical function) &lt;span
class=&quot;math inline&quot;&gt;\(f:\mathbb{R}^p\to\mathbb{R}^q\)&lt;/span&gt; from the
old variables to the new ones, such that it has an inverse &lt;span
class=&quot;math inline&quot;&gt;\(f^{-1}:\mathbb{R}^q\to\mathbb{R}^p\)&lt;/span&gt;, which
restores the original data. The function &lt;span
class=&quot;math inline&quot;&gt;\(f\)&lt;/span&gt; is then applied to each row of &lt;span
class=&quot;math inline&quot;&gt;\(X\)&lt;/span&gt; to get the new data matrix, &lt;span
class=&quot;math inline&quot;&gt;\(Z\)&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;This formulation is too general, however. For example, because &lt;span
class=&quot;math inline&quot;&gt;\(\mathbb{R}^p\)&lt;/span&gt; is isomoprhic (as a set) to
&lt;span class=&quot;math inline&quot;&gt;\(\mathbb{R}\)&lt;/span&gt;, we can encode
everything in a single variable. But the relationship between the old
variables and the new one will be very non-trivial. The new variable,
even though it encodes precisely the same information, would tell us
nothing meaningful about the data.&lt;/p&gt;
&lt;p&gt;Therefore, we need to impose some restrictions on the nature of &lt;span
class=&quot;math inline&quot;&gt;\(f\)&lt;/span&gt;. Here we require that &lt;span
class=&quot;math inline&quot;&gt;\(f\)&lt;/span&gt; be a linear function; so that &lt;span
class=&quot;math inline&quot;&gt;\(f(\mathrm{x})=\mathrm{x}A\)&lt;/span&gt;, where &lt;span
class=&quot;math inline&quot;&gt;\(\mathrm{x}\)&lt;/span&gt; is a row of &lt;span
class=&quot;math inline&quot;&gt;\(X\)&lt;/span&gt; and &lt;span
class=&quot;math inline&quot;&gt;\(A\)&lt;/span&gt; is a &lt;span
class=&quot;math inline&quot;&gt;\(p\times q\)&lt;/span&gt; matrix. The new data matrix can
be then computed as &lt;span class=&quot;math inline&quot;&gt;\(Z = X A\)&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;Now it’s no longer possible to squeeze everything into a single
variable; for the inverse mapping to exist we need &lt;span
class=&quot;math inline&quot;&gt;\(q\geq p\)&lt;/span&gt;. Because we are trying to
&lt;em&gt;reduce&lt;/em&gt; the dimensionality of the data, not &lt;em&gt;expand&lt;/em&gt; it,
we’ll stick with &lt;span class=&quot;math inline&quot;&gt;\(q=p\)&lt;/span&gt;, so &lt;span
class=&quot;math inline&quot;&gt;\(A\)&lt;/span&gt; is an invertible &lt;span
class=&quot;math inline&quot;&gt;\(p\times p\)&lt;/span&gt; square matrix.&lt;/p&gt;
&lt;p&gt;But even an invertible linear transformation is too general for PCA
because it does not preserve the total variance.&lt;/p&gt;
&lt;p&gt;From now on, we shall assume that the sample mean of each column of
&lt;span class=&quot;math inline&quot;&gt;\(X\)&lt;/span&gt; is 0. This can be achieved by
subtracting from each column its mean value. Under this assumption, the
covariance matrix of &lt;span class=&quot;math inline&quot;&gt;\(X\)&lt;/span&gt; has a very
simple form: &lt;span class=&quot;math inline&quot;&gt;\(\mathrm{Cov}(X)=\frac1{n-1}
X&amp;#39;X\)&lt;/span&gt;. Also, if the columns of &lt;span
class=&quot;math inline&quot;&gt;\(X\)&lt;/span&gt; have zero mean, so do the column of
&lt;span class=&quot;math inline&quot;&gt;\(Z=XA\)&lt;/span&gt;:&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;math display&quot;&gt;\[
\begin{split}
\left(\frac1n\quad \frac1n\quad \ldots\quad \frac1n\right) Z &amp;amp;=
\left(\frac1n\quad \frac1n\quad \ldots\quad \frac1n\right) X A\\ &amp;amp;=
\left(0\quad 0\quad \ldots\quad 0\right) A\\ &amp;amp;=
\left(0\quad 0\quad \ldots\quad 0\right).
\end{split}
\]&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Then the covariance matrix of &lt;span class=&quot;math inline&quot;&gt;\(Z\)&lt;/span&gt;
is &lt;span class=&quot;math display&quot;&gt;\[\mathrm{Cov}(Z)=\frac1{n-1}
Z&amp;#39;Z=\frac1{n-1} A&amp;#39;X&amp;#39;XA=A&amp;#39;\mathrm{Cov}(X)A.\]&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;The total variance of &lt;span class=&quot;math inline&quot;&gt;\(X\)&lt;/span&gt; is the
sum of the diagonal elements in the covariance matrix &lt;span
class=&quot;math inline&quot;&gt;\(\mathrm{Cov}(X)\)&lt;/span&gt;, i.e. its &lt;em&gt;trace&lt;/em&gt;,
&lt;span class=&quot;math inline&quot;&gt;\(\mathrm{Tr}(\mathrm{Cov}(X))\)&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;In general, a transformation &lt;span
class=&quot;math inline&quot;&gt;\(\mathrm{Cov}(X)\mapsto
A&amp;#39;\mathrm{Cov}(X)A\)&lt;/span&gt; does not preserve the trace of the
matrix &lt;span class=&quot;math inline&quot;&gt;\(\mathrm{Cov}(X)\)&lt;/span&gt;. For
instance, multiplying all variables by a constant number &lt;span
class=&quot;math inline&quot;&gt;\(c\)&lt;/span&gt; is a linear transformation with matrix
&lt;span class=&quot;math inline&quot;&gt;\(c\cdot I\)&lt;/span&gt;. This transformation will
inflate the total variance by a factor of &lt;span
class=&quot;math inline&quot;&gt;\(c^2\)&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;To ensure that the total variance does not change, we require that
&lt;span class=&quot;math inline&quot;&gt;\(\mathrm{Cov}(X)\mapsto
A&amp;#39;\mathrm{Cov}(X)A\)&lt;/span&gt; is a &lt;a
href=&quot;https://en.wikipedia.org/wiki/Matrix_similarity&quot;&gt;similarity
transformation&lt;/a&gt;, which always preserves the trace of the matrix it
transforms. This is equivalent to saying that &lt;span
class=&quot;math inline&quot;&gt;\(A^{-1}=A&amp;#39;\)&lt;/span&gt;, or that &lt;span
class=&quot;math inline&quot;&gt;\(A\)&lt;/span&gt; is &lt;a
href=&quot;https://en.wikipedia.org/wiki/Orthogonal_matrix&quot;&gt;orthogonal&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Preserving the total variance is not the only (or even an important)
reason to require that the change of variables is an orthogonal
transformation. As we saw earlier, the transformation &lt;span
class=&quot;math inline&quot;&gt;\(c\cdot I\)&lt;/span&gt; inflates the total variance by
the factor of &lt;span class=&quot;math inline&quot;&gt;\(c^2\)&lt;/span&gt;, but it does so
by uniformly inflating the variance of each variable. So when we compute
the fraction of the total variance explained by the variables, that
common factor cancels out.&lt;/p&gt;
&lt;p&gt;The real problem is that we could rescale individual variables.
Consider a &lt;span class=&quot;math inline&quot;&gt;\(2\times 2\)&lt;/span&gt; matrix&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;math display&quot;&gt;\[
A=\pmatrix{a_{11}&amp;amp;0\\0&amp;amp;a_{22}}.
\]&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Unless &lt;span class=&quot;math inline&quot;&gt;\(a_{11}\)&lt;/span&gt; and &lt;span
class=&quot;math inline&quot;&gt;\(a_{22}\)&lt;/span&gt; are &lt;span
class=&quot;math inline&quot;&gt;\(\pm 1\)&lt;/span&gt;, &lt;span
class=&quot;math inline&quot;&gt;\(A\)&lt;/span&gt; is not orthogonal. So, in general,
&lt;span class=&quot;math inline&quot;&gt;\(A\)&lt;/span&gt; will not preserve the total
variance of &lt;em&gt;every&lt;/em&gt; matrix. However, for &lt;em&gt;any given&lt;/em&gt;
matrix &lt;span class=&quot;math inline&quot;&gt;\(X\)&lt;/span&gt;, there are many possible
values of &lt;span class=&quot;math inline&quot;&gt;\(a_{11}\)&lt;/span&gt; and &lt;span
class=&quot;math inline&quot;&gt;\(a_{22}\)&lt;/span&gt; that will preserve &lt;span
class=&quot;math inline&quot;&gt;\(X\)&lt;/span&gt;’s total variance: they form an
ellipse&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;math display&quot;&gt;\[a_{11}^2\mathrm{Var}(X_{\cdot
1})+a_{22}^2\mathrm{Var}(X_{\cdot 2})=\mathrm{Var}(X_{\cdot
1})+\mathrm{Var}(X_{\cdot 2}).\]&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Recall that the objective of PCA is make the first variable explain
the maximum fraction of the total variance. By choosing &lt;span
class=&quot;math inline&quot;&gt;\(a_{22}\)&lt;/span&gt; close to zero (and inferring &lt;span
class=&quot;math inline&quot;&gt;\(a_{11}\)&lt;/span&gt; from the above equation), we can
make the fraction of variance “explained” by the first principal
component arbitrarily close to 1 without transforming the data in any
meaningful way.&lt;/p&gt;
&lt;p&gt;This kind of cheating is made impossible by requiring that &lt;span
class=&quot;math inline&quot;&gt;\(A\)&lt;/span&gt; is orthogonal.&lt;/p&gt;
&lt;p&gt;Now let’s talk about &lt;em&gt;why&lt;/em&gt; it’s desirable to maximize the
explained variance. The typical use of PCA is to keep only the first
&lt;span class=&quot;math inline&quot;&gt;\(k&amp;lt;p\)&lt;/span&gt; principal components.
Because PCA is an orthogonal transformation, this corresponds to
projecting the data from its original &lt;span
class=&quot;math inline&quot;&gt;\(p\)&lt;/span&gt;-dimensional space to a &lt;span
class=&quot;math inline&quot;&gt;\(k\)&lt;/span&gt;-dimensional subspace. The remaining
&lt;span class=&quot;math inline&quot;&gt;\(p-k\)&lt;/span&gt; components are lost in this
projection; so it makes sense to minimize the variability of the data in
those directions. Because the total variance is constant, minimizing the
variance of the last &lt;span class=&quot;math inline&quot;&gt;\(p-k\)&lt;/span&gt; variables
is the same as maximizing the variance of the first &lt;span
class=&quot;math inline&quot;&gt;\(k\)&lt;/span&gt; variables. The choices we make in PCA
are motivated precisely by this objective:&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;PCA itself is designed to maximize the variance of the first &lt;span
class=&quot;math inline&quot;&gt;\(k\)&lt;/span&gt; components, and minimize the variance
of the last &lt;span class=&quot;math inline&quot;&gt;\(p-k\)&lt;/span&gt; components,
compared to all other orthogonal transformations.&lt;/li&gt;
&lt;li&gt;We choose the first &lt;span class=&quot;math inline&quot;&gt;\(k\)&lt;/span&gt;
components, and not just &lt;em&gt;some&lt;/em&gt; &lt;span
class=&quot;math inline&quot;&gt;\(k\)&lt;/span&gt; components, because they have the
highest variance out of all principal components.&lt;/li&gt;
&lt;li&gt;We try to choose &lt;span class=&quot;math inline&quot;&gt;\(k\)&lt;/span&gt; big enough
to make the lost information — the variance of the last &lt;span
class=&quot;math inline&quot;&gt;\(p-k\)&lt;/span&gt; components — sufficiently small.&lt;/li&gt;
&lt;/ol&gt;
</description>
                        <pubDate>Mon, 11 Dec 2017 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2017-12-11-pca-explained-variance</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2017-12-11-pca-explained-variance.html</guid>
                </item>
        
                <item>
                        <title>Introduction to golden testing</title>
                        <description>&lt;p&gt;Golden tests are like unit tests, except the expected output is
stored in a separate file. I learned about them in 2010 from Max
Grigorev at &lt;a
href=&quot;https://wiki.haskell.org/ZuriHac2010&quot;&gt;ZuriHac&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Let’s say you want to test Python’s &lt;code&gt;json&lt;/code&gt; module. One way
to do that would be to encode an object and compare the result to a
reference string:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb1&quot;&gt;&lt;pre
class=&quot;sourceCode python&quot;&gt;&lt;code class=&quot;sourceCode python&quot;&gt;&lt;span id=&quot;cb1-1&quot;&gt;&lt;a href=&quot;#cb1-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;im&quot;&gt;import&lt;/span&gt; json&lt;/span&gt;
&lt;span id=&quot;cb1-2&quot;&gt;&lt;a href=&quot;#cb1-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-3&quot;&gt;&lt;a href=&quot;#cb1-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;cf&quot;&gt;assert&lt;/span&gt;(json.dumps([&lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;,&lt;span class=&quot;dv&quot;&gt;2&lt;/span&gt;,&lt;span class=&quot;dv&quot;&gt;3&lt;/span&gt;]) &lt;span class=&quot;op&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;quot;[1, 2, 3]&amp;quot;&lt;/span&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Alternatively, you could create a file with contents&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[1, 2, 3]&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;and read it to know the expected output:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb3&quot;&gt;&lt;pre
class=&quot;sourceCode python&quot;&gt;&lt;code class=&quot;sourceCode python&quot;&gt;&lt;span id=&quot;cb3-1&quot;&gt;&lt;a href=&quot;#cb3-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;im&quot;&gt;import&lt;/span&gt; json&lt;/span&gt;
&lt;span id=&quot;cb3-2&quot;&gt;&lt;a href=&quot;#cb3-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-3&quot;&gt;&lt;a href=&quot;#cb3-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;cf&quot;&gt;with&lt;/span&gt; &lt;span class=&quot;bu&quot;&gt;open&lt;/span&gt;(&lt;span class=&quot;st&quot;&gt;&amp;quot;example1.json&amp;quot;&lt;/span&gt;, &lt;span class=&quot;st&quot;&gt;&amp;quot;r&amp;quot;&lt;/span&gt;) &lt;span class=&quot;im&quot;&gt;as&lt;/span&gt; ex1_file:&lt;/span&gt;
&lt;span id=&quot;cb3-4&quot;&gt;&lt;a href=&quot;#cb3-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    ex1 &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; ex1_file.read().rstrip()&lt;/span&gt;
&lt;span id=&quot;cb3-5&quot;&gt;&lt;a href=&quot;#cb3-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;cf&quot;&gt;assert&lt;/span&gt;(json.dumps([&lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;,&lt;span class=&quot;dv&quot;&gt;2&lt;/span&gt;,&lt;span class=&quot;dv&quot;&gt;3&lt;/span&gt;]) &lt;span class=&quot;op&quot;&gt;==&lt;/span&gt; ex1)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The file &lt;code&gt;example1.json&lt;/code&gt; is called a &lt;em&gt;golden&lt;/em&gt;
file.&lt;/p&gt;
&lt;p&gt;Here are some advantages of golden tests over ordinary unit
tests:&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;&lt;p&gt;If the expected output is &lt;strong&gt;large in size&lt;/strong&gt;, it may
be impractical to put it inside the source code.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;No need to &lt;strong&gt;escape quotes or binary data&lt;/strong&gt; in the
expected output.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;When you add a &lt;strong&gt;new test&lt;/strong&gt;, your testing framework
can &lt;strong&gt;generate the missing golden file&lt;/strong&gt; from the current
output of the function.&lt;/p&gt;
&lt;p&gt;It is best if you can write down the expected output without looking
at the actual output, but it is not always possible. The output may be
too big to type it character by character, or it may be hard to predict.
For instance, in the json example, you couldn’t tell in advance whether
there would be spaces between array elements or not. So often what you
do is launch an interactive interpreter (if your language of choice even
has one), run the function, and then copy-paste its output into the test
code.&lt;/p&gt;
&lt;p&gt;This process can be easily automated if you use golden
files.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The expected output can be &lt;strong&gt;automatically
updated&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Say you changed your json module to replace some of the spaces with
newlines to make the output more aesthetically pleasing. You have 40
test cases that need updating. Can you imagine doing this by hand?&lt;/p&gt;
&lt;p&gt;With golden tests, you can tell your test framework to update all
golden files from the current outputs, then check &lt;code&gt;git diff&lt;/code&gt;
to ensure that all changes are valid, and commit them.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If some of your tests suddently started failing, &lt;strong&gt;you can
use &lt;code&gt;diff&lt;/code&gt;&lt;/strong&gt; or other such tools to compare the golden
file to the actual file and figure out what exactly changed. Perhaps
your testing framework could even show the diff automatically on test
failure?&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;While advantages 1-2 are automatic, 3-5 require special support from
your testing framework. The rest of this article will be focused on a
Haskell testing framework &lt;a
href=&quot;https://github.com/UnkindPartition/tasty&quot;&gt;tasty&lt;/a&gt; and its add-on
package for golden tests, &lt;a
href=&quot;https://github.com/UnkindPartition/tasty-golden&quot;&gt;tasty-golden&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;basic-usage&quot;&gt;Basic usage&lt;/h2&gt;
&lt;p&gt;To illustrate how tasty-golden works, consider this yaml-to-json
conversion module:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb4&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb4-1&quot;&gt;&lt;a href=&quot;#cb4-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;{-# LANGUAGE TypeApplications #-}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-2&quot;&gt;&lt;a href=&quot;#cb4-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;module&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;YamlToJson&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-3&quot;&gt;&lt;a href=&quot;#cb4-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-4&quot;&gt;&lt;a href=&quot;#cb4-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;qualified&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Data.Yaml&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Y&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-5&quot;&gt;&lt;a href=&quot;#cb4-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Data.Aeson&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;J&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-6&quot;&gt;&lt;a href=&quot;#cb4-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;qualified&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Data.ByteString.Lazy&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;LBS&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-7&quot;&gt;&lt;a href=&quot;#cb4-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-8&quot;&gt;&lt;a href=&quot;#cb4-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;yamlToJson ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;LBS.ByteString&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;LBS.ByteString&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-9&quot;&gt;&lt;a href=&quot;#cb4-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;yamlToJson &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; J.encode &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt; Y.decode &lt;span class=&quot;op&quot;&gt;@&lt;/span&gt;&lt;span class=&quot;dt&quot;&gt;Value&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt; LBS.toStrict&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Because JSON contains quotes and YAML spans multiple lines, it is not
very practical to store them as string literals in the source code file.
Instead, you will keep them both in files.&lt;/p&gt;
&lt;p&gt;Note that the name “golden file” only refers to the file containing
the &lt;em&gt;output&lt;/em&gt;, not the &lt;em&gt;input&lt;/em&gt;. There is no requirement
that the input is stored in a file or that there even is any “input” at
all; but in practice it is often convenient to store them both in files
so that there is an input file for every output file and vice versa.&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb5&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb5-1&quot;&gt;&lt;a href=&quot;#cb5-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Test.Tasty&lt;/span&gt; (defaultMain, &lt;span class=&quot;dt&quot;&gt;TestTree&lt;/span&gt;, testGroup)&lt;/span&gt;
&lt;span id=&quot;cb5-2&quot;&gt;&lt;a href=&quot;#cb5-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Test.Tasty.Golden&lt;/span&gt; (goldenVsString, findByExtension)&lt;/span&gt;
&lt;span id=&quot;cb5-3&quot;&gt;&lt;a href=&quot;#cb5-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;qualified&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Data.ByteString.Lazy&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;LBS&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-4&quot;&gt;&lt;a href=&quot;#cb5-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;YamlToJson&lt;/span&gt; (yamlToJson)&lt;/span&gt;
&lt;span id=&quot;cb5-5&quot;&gt;&lt;a href=&quot;#cb5-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;System.FilePath&lt;/span&gt; (takeBaseName, replaceExtension)&lt;/span&gt;
&lt;span id=&quot;cb5-6&quot;&gt;&lt;a href=&quot;#cb5-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-7&quot;&gt;&lt;a href=&quot;#cb5-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;main ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;IO&lt;/span&gt; ()&lt;/span&gt;
&lt;span id=&quot;cb5-8&quot;&gt;&lt;a href=&quot;#cb5-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;main &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; defaultMain &lt;span class=&quot;op&quot;&gt;=&amp;lt;&amp;lt;&lt;/span&gt; goldenTests&lt;/span&gt;
&lt;span id=&quot;cb5-9&quot;&gt;&lt;a href=&quot;#cb5-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-10&quot;&gt;&lt;a href=&quot;#cb5-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;goldenTests ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;IO&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;TestTree&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-11&quot;&gt;&lt;a href=&quot;#cb5-11&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;goldenTests &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-12&quot;&gt;&lt;a href=&quot;#cb5-12&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  yamlFiles &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; findByExtension [&lt;span class=&quot;st&quot;&gt;&amp;quot;.yaml&amp;quot;&lt;/span&gt;] &lt;span class=&quot;st&quot;&gt;&amp;quot;.&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-13&quot;&gt;&lt;a href=&quot;#cb5-13&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;fu&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; testGroup &lt;span class=&quot;st&quot;&gt;&amp;quot;YamlToJson golden tests&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-14&quot;&gt;&lt;a href=&quot;#cb5-14&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    [ goldenVsString&lt;/span&gt;
&lt;span id=&quot;cb5-15&quot;&gt;&lt;a href=&quot;#cb5-15&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;        (takeBaseName yamlFile) &lt;span class=&quot;co&quot;&gt;-- test name&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-16&quot;&gt;&lt;a href=&quot;#cb5-16&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;        jsonFile &lt;span class=&quot;co&quot;&gt;-- golden file path&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-17&quot;&gt;&lt;a href=&quot;#cb5-17&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;        (yamlToJson &lt;span class=&quot;op&quot;&gt;&amp;lt;$&amp;gt;&lt;/span&gt; LBS.readFile yamlFile) &lt;span class=&quot;co&quot;&gt;-- action whose result is tested&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-18&quot;&gt;&lt;a href=&quot;#cb5-18&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;op&quot;&gt;|&lt;/span&gt; yamlFile &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; yamlFiles&lt;/span&gt;
&lt;span id=&quot;cb5-19&quot;&gt;&lt;a href=&quot;#cb5-19&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    , &lt;span class=&quot;kw&quot;&gt;let&lt;/span&gt; jsonFile &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; replaceExtension yamlFile &lt;span class=&quot;st&quot;&gt;&amp;quot;.json&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-20&quot;&gt;&lt;a href=&quot;#cb5-20&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    ]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This is all the code you need to support one, two, or a thousand test
cases. When run, this code will:&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;find all &lt;code&gt;.yaml&lt;/code&gt; files in the current directory&lt;/li&gt;
&lt;li&gt;for each &lt;code&gt;.yaml&lt;/code&gt; file, construct a golden test that
evaluates &lt;code&gt;yamlToJson&lt;/code&gt; on the input read from file and
compares the result to the golden file, which has the name and the
&lt;code&gt;.json&lt;/code&gt; extension&lt;/li&gt;
&lt;li&gt;put all individual tests in a test group and pass it to
&lt;code&gt;defaultMain&lt;/code&gt; for execution&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;To see how this works in practice, create an input file,
&lt;code&gt;fruits.yaml&lt;/code&gt;, with the following contents:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb6&quot;&gt;&lt;pre
class=&quot;sourceCode yaml&quot;&gt;&lt;code class=&quot;sourceCode yaml&quot;&gt;&lt;span id=&quot;cb6-1&quot;&gt;&lt;a href=&quot;#cb6-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;at&quot;&gt; orange&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-2&quot;&gt;&lt;a href=&quot;#cb6-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;at&quot;&gt; apple&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-3&quot;&gt;&lt;a href=&quot;#cb6-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;at&quot;&gt; banana&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now run your test suite (note: in a proper cabalized project, you’d
run &lt;code&gt;cabal test&lt;/code&gt; or &lt;code&gt;stack test&lt;/code&gt; instead):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% stack runghc test.hs
YamlToJson golden tests
  fruits: OK
    Golden file did not exist; created

All 1 tests passed (0.00s)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;tasty-golden realized that this is a new test case because the golden
file was absent, so it went ahead and initialized the golden file based
on the function’s output. You can now examine the file to see if it
makes sense:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% cat fruits.json
[&amp;quot;orange&amp;quot;,&amp;quot;apple&amp;quot;,&amp;quot;banana&amp;quot;]&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If you are happy with it, check in both input and output files to
git. This is important so that your collaborators can run the tests, but
it also helps when dealing with failing tests, as you’ll see next.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% git add fruits.yaml fruits.json &amp;amp;&amp;amp; git commit -m &amp;quot;fruits test case&amp;quot;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;dealing-with-test-failures&quot;&gt;Dealing with test failures&lt;/h2&gt;
&lt;p&gt;Occasionally, your tests will fail. A test that cannot fail is a
useless test.&lt;/p&gt;
&lt;p&gt;A golden test fails when the actual output does not match the
contents of the golden file. You then need to figure out whether this is
a bug or an intentional code change.&lt;/p&gt;
&lt;p&gt;Let’s say you decide that the output of &lt;code&gt;yamlToJson&lt;/code&gt;
should end with a newline.&lt;/p&gt;
&lt;p&gt;The new function definition is&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb10&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb10-1&quot;&gt;&lt;a href=&quot;#cb10-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;yamlToJson &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; (&lt;span class=&quot;op&quot;&gt;&amp;lt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;quot;\n&amp;quot;&lt;/span&gt;) &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt; J.encode &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt; Y.decode &lt;span class=&quot;op&quot;&gt;@&lt;/span&gt;&lt;span class=&quot;dt&quot;&gt;Value&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt; LBS.toStrict&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now run the test suite:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% stack runghc test.hs
YamlToJson golden tests
  fruits: FAIL
    Test output was different from &amp;#39;./fruits.json&amp;#39;. It was: &amp;quot;[\&amp;quot;orange\&amp;quot;,\&amp;quot;apple\&amp;quot;,\&amp;quot;banana\&amp;quot;]\n&amp;quot;

1 out of 1 tests failed (0.00s)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Ok, this is not very helpful. There are two main ways to get better
diagnostics. One is to use the &lt;code&gt;goldenVsStringDiff&lt;/code&gt; function
as an alternative to &lt;code&gt;goldenVsString&lt;/code&gt;. This will include the
diff right in the tasty output.&lt;/p&gt;
&lt;p&gt;But my preferred workflow is to use git for this. First, rerun the
tests and pass the &lt;code&gt;--accept&lt;/code&gt; option. This will update the
golden files with the new output:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% stack runghc -- test.hs --accept
YamlToJson golden tests
  fruits: OK
    Accepted the new version

All 1 tests passed (0.00s)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, because your golden file is tracked by git, you can examine the
differences between the old and new golden files with
&lt;code&gt;git diff&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% git diff
diff --git fruits.json fruits.json
index c244c0a..ed447d4 100644
--- fruits.json
+++ fruits.json
@@ -1 +1 @@
-[&amp;quot;orange&amp;quot;,&amp;quot;apple&amp;quot;,&amp;quot;banana&amp;quot;]
\ No newline at end of file
+[&amp;quot;orange&amp;quot;,&amp;quot;apple&amp;quot;,&amp;quot;banana&amp;quot;]&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Because this is the change you expected, you can now commit the
updated file to git.&lt;/p&gt;
&lt;p&gt;This workflow lets you use all the powerful &lt;code&gt;git diff&lt;/code&gt;
options like &lt;code&gt;--color-words&lt;/code&gt;, or even launch a graphical diff
tool like kdiff3 with &lt;code&gt;git difftool&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&quot;see-also&quot;&gt;See also&lt;/h2&gt;
&lt;p&gt;&lt;a
href=&quot;https://kseo.github.io/posts/2016-12-15-golden-tests-are-tasty.html&quot;&gt;Golden
tests are tasty&lt;/a&gt; by Kwang Yul Seo&lt;/p&gt;
</description>
                        <pubDate>Mon, 04 Dec 2017 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2017-12-04-golden-tests</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2017-12-04-golden-tests.html</guid>
                </item>
        
                <item>
                        <title>Algebra of permutations in R</title>
                        <description>&lt;p&gt;A &lt;a
href=&quot;https://en.wikipedia.org/wiki/Permutation#Definition_and_notations&quot;&gt;permutation&lt;/a&gt;
is a mathematical function that maps numbers from the set &lt;span
class=&quot;math inline&quot;&gt;\(\{1,2,\ldots,n\}\)&lt;/span&gt; to other numbers from
the same set.&lt;/p&gt;
&lt;p&gt;An example of a permutation for &lt;span
class=&quot;math inline&quot;&gt;\(n=5\)&lt;/span&gt; would be&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;math display&quot;&gt;\[
s=\begin{pmatrix}
  1 &amp;amp; 2 &amp;amp; 3 &amp;amp; 4 &amp;amp; 5 \\
  2 &amp;amp; 5 &amp;amp; 4 &amp;amp; 3 &amp;amp; 1
\end{pmatrix}
\]&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;This two-line notation denotes a function &lt;span
class=&quot;math inline&quot;&gt;\(s\)&lt;/span&gt; such that &lt;span
class=&quot;math inline&quot;&gt;\(s(1)=2\)&lt;/span&gt;, &lt;span
class=&quot;math inline&quot;&gt;\(s(2)=5\)&lt;/span&gt; and so on.&lt;/p&gt;
&lt;p&gt;In R, we can represent a permutation by its second row, and assume
that the first row implicitly consists of the numbers from &lt;span
class=&quot;math inline&quot;&gt;\(1\)&lt;/span&gt; to &lt;span
class=&quot;math inline&quot;&gt;\(n\)&lt;/span&gt; in the ascending order:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;s &amp;lt;- c(2, 5, 4, 3, 1)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;An R vector represents a permutation if and only if it consists of
&lt;code&gt;n&lt;/code&gt; integers between &lt;code&gt;1&lt;/code&gt; and &lt;code&gt;n&lt;/code&gt;, and
each integer occurs in the vector exactly once.&lt;/p&gt;
&lt;p&gt;Here is how the mathematics of permutations maps to R:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The application &lt;span class=&quot;math inline&quot;&gt;\(s(i)\)&lt;/span&gt; (where
&lt;span class=&quot;math inline&quot;&gt;\(i\in \{1,\ldots,n\}\)&lt;/span&gt;) corresponds to
&lt;code&gt;s[i]&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;The composition of permutations &lt;span
class=&quot;math inline&quot;&gt;\(s\)&lt;/span&gt; and &lt;span
class=&quot;math inline&quot;&gt;\(t\)&lt;/span&gt;, &lt;span class=&quot;math inline&quot;&gt;\(s \circ
t\)&lt;/span&gt;, corresponds to the vector &lt;code&gt;s[t]&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;the identity permutation, &lt;span
class=&quot;math inline&quot;&gt;\(\mathrm{id}\)&lt;/span&gt;, corresponds to the vector
&lt;code&gt;1:n&lt;/code&gt;, because &lt;code&gt;s[1:n] == s&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;The inverse of a permutation &lt;span class=&quot;math inline&quot;&gt;\(s\)&lt;/span&gt;,
&lt;span class=&quot;math inline&quot;&gt;\(s^{-1}\)&lt;/span&gt;, corresponds to the vector
&lt;code&gt;order(s)&lt;/code&gt;. This is because
&lt;code&gt;s[order(s)] == 1:s&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;sample(n)&lt;/code&gt; gives a random permutation of size
&lt;code&gt;n&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The main use for permutations in R is to rearrange the data. If
&lt;code&gt;s&lt;/code&gt; is a permutation vector and &lt;code&gt;d&lt;/code&gt; is an
arbitrary vector (i.e. its elements are not necessarily numbers from
&lt;code&gt;1&lt;/code&gt; to &lt;code&gt;n&lt;/code&gt;), then &lt;code&gt;d[s]&lt;/code&gt; is some
rearrangement of &lt;code&gt;d&lt;/code&gt;. Specifically,
&lt;code&gt;d[s][i] == d[s[i]]&lt;/code&gt;, so the &lt;code&gt;i&lt;/code&gt;th element of
&lt;code&gt;d[s]&lt;/code&gt; is the &lt;code&gt;s[i]&lt;/code&gt;th element of
&lt;code&gt;d&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Often we need to solve the reverse problem: we need to move the
&lt;code&gt;i&lt;/code&gt;th element of &lt;code&gt;d&lt;/code&gt; to the position
&lt;code&gt;s[i]&lt;/code&gt; in the resulting vector. Because the inverse
permutation of &lt;code&gt;s&lt;/code&gt; is &lt;code&gt;order(s)&lt;/code&gt;,
&lt;code&gt;d[order(s)]&lt;/code&gt; is exactly what we need.&lt;/p&gt;
&lt;p&gt;As I explain in &lt;a href=&quot;/articles/2016-03-19-rank-vs-order-r&quot;&gt;rank
vs. order in R&lt;/a&gt;, &lt;code&gt;rank(a)&lt;/code&gt; and &lt;code&gt;order(a)&lt;/code&gt; are
inverse permutations of each other. But above I said that
&lt;code&gt;order(s)&lt;/code&gt; is the inverse of &lt;code&gt;s&lt;/code&gt; itself. It
follows, therefore, that when &lt;code&gt;s&lt;/code&gt; is a permutation vector,
&lt;code&gt;rank(s)&lt;/code&gt; coincides with &lt;code&gt;s&lt;/code&gt; itself:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb2&quot;&gt;&lt;pre class=&quot;sourceCode r&quot;&gt;&lt;code class=&quot;sourceCode r&quot;&gt;&lt;span id=&quot;cb2-1&quot;&gt;&lt;a href=&quot;#cb2-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;s &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;sample&lt;/span&gt;(&lt;span class=&quot;dv&quot;&gt;100&lt;/span&gt;)&lt;/span&gt;
&lt;span id=&quot;cb2-2&quot;&gt;&lt;a href=&quot;#cb2-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;fu&quot;&gt;all&lt;/span&gt;(&lt;span class=&quot;fu&quot;&gt;rank&lt;/span&gt;(s) &lt;span class=&quot;sc&quot;&gt;==&lt;/span&gt; s)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;pre&gt;&lt;code&gt;[1] TRUE&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;example-sort-monthly-data&quot;&gt;Example: sort monthly data&lt;/h2&gt;
&lt;p&gt;As an example, let’s use the algebra of permutations to put some
monthly data in the chronological order:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb4&quot;&gt;&lt;pre class=&quot;sourceCode r&quot;&gt;&lt;code class=&quot;sourceCode r&quot;&gt;&lt;span id=&quot;cb4-1&quot;&gt;&lt;a href=&quot;#cb4-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;fu&quot;&gt;set.seed&lt;/span&gt;(&lt;span class=&quot;dv&quot;&gt;2017-11-18&lt;/span&gt;)&lt;/span&gt;
&lt;span id=&quot;cb4-2&quot;&gt;&lt;a href=&quot;#cb4-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;v &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;rpois&lt;/span&gt;(&lt;span class=&quot;dv&quot;&gt;12&lt;/span&gt;, &lt;span class=&quot;dv&quot;&gt;50&lt;/span&gt;)&lt;/span&gt;
&lt;span id=&quot;cb4-3&quot;&gt;&lt;a href=&quot;#cb4-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;fu&quot;&gt;names&lt;/span&gt;(v) &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;sample&lt;/span&gt;(month.abb)&lt;/span&gt;
&lt;span id=&quot;cb4-4&quot;&gt;&lt;a href=&quot;#cb4-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;v&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;pre&gt;&lt;code&gt;Oct Mar Jul Aug Sep Nov Dec Apr Jun Jan May Feb 
 50  47  48  53  42  56  61  59  56  57  50  58 &lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The proper chronological order is given by the &lt;code&gt;month.abb&lt;/code&gt;
vector:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt; [1] &amp;quot;Jan&amp;quot; &amp;quot;Feb&amp;quot; &amp;quot;Mar&amp;quot; &amp;quot;Apr&amp;quot; &amp;quot;May&amp;quot; &amp;quot;Jun&amp;quot; &amp;quot;Jul&amp;quot; &amp;quot;Aug&amp;quot; &amp;quot;Sep&amp;quot; &amp;quot;Oct&amp;quot; &amp;quot;Nov&amp;quot; &amp;quot;Dec&amp;quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Because our goal is to rearrange the vector &lt;code&gt;v&lt;/code&gt;, the
solution will have the form &lt;code&gt;v[order(s)]&lt;/code&gt;, where the
permutation &lt;code&gt;s&lt;/code&gt; specifies, for each index &lt;code&gt;i&lt;/code&gt;,
that the &lt;code&gt;i&lt;/code&gt;th element should be moved to the
&lt;code&gt;s[i]&lt;/code&gt;th position.&lt;/p&gt;
&lt;p&gt;Our strategy will be to build &lt;code&gt;s&lt;/code&gt; as a composition of two
permutations, &lt;code&gt;x[y]&lt;/code&gt;, where &lt;code&gt;y&lt;/code&gt; transforms our
random order into the alphabetical order of month names, and
&lt;code&gt;x&lt;/code&gt; then transforms the alphabetical order to the
chronological order. (Remember that &lt;code&gt;x[y][i] == x[y[i]]&lt;/code&gt;, so
&lt;code&gt;y&lt;/code&gt; is the permutation that gets applied first.)&lt;/p&gt;
&lt;p&gt;We need &lt;code&gt;y&lt;/code&gt; to send the month name
&lt;code&gt;names(v)[i]&lt;/code&gt; to its correct position in the
alphabetically-sorted vector. This position is given by
&lt;code&gt;rank(names(v))[i]&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb7&quot;&gt;&lt;pre class=&quot;sourceCode r&quot;&gt;&lt;code class=&quot;sourceCode r&quot;&gt;&lt;span id=&quot;cb7-1&quot;&gt;&lt;a href=&quot;#cb7-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;y &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;rank&lt;/span&gt;(&lt;span class=&quot;fu&quot;&gt;names&lt;/span&gt;(v))&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Let’s now consider &lt;code&gt;x&lt;/code&gt;. It must send an index
&lt;code&gt;i&lt;/code&gt; in the alphabetically sorted vector to the corresponding
index in the chronological vector. &lt;code&gt;rank(month.abb)&lt;/code&gt; sends
indexes from the chronological vector to the alphabetical vector, so
&lt;code&gt;x&lt;/code&gt; must be the inverse of that:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb8&quot;&gt;&lt;pre class=&quot;sourceCode r&quot;&gt;&lt;code class=&quot;sourceCode r&quot;&gt;&lt;span id=&quot;cb8-1&quot;&gt;&lt;a href=&quot;#cb8-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;x &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;order&lt;/span&gt;(&lt;span class=&quot;fu&quot;&gt;rank&lt;/span&gt;(month.abb))&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Let’s see if we got &lt;code&gt;x&lt;/code&gt; and &lt;code&gt;y&lt;/code&gt; right:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb9&quot;&gt;&lt;pre class=&quot;sourceCode r&quot;&gt;&lt;code class=&quot;sourceCode r&quot;&gt;&lt;span id=&quot;cb9-1&quot;&gt;&lt;a href=&quot;#cb9-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;s &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; x[y]&lt;/span&gt;
&lt;span id=&quot;cb9-2&quot;&gt;&lt;a href=&quot;#cb9-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;v[&lt;span class=&quot;fu&quot;&gt;order&lt;/span&gt;(s)]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;pre&gt;&lt;code&gt;Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec 
 57  58  47  59  50  56  48  53  42  50  56  61 &lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Yay!&lt;/p&gt;
&lt;p&gt;Now, let’s simplify our code. Let’s denote
&lt;code&gt;rank(names(v))&lt;/code&gt; as &lt;span class=&quot;math inline&quot;&gt;\(r_1\)&lt;/span&gt;
and &lt;code&gt;rank(month.abb)&lt;/code&gt; as &lt;span
class=&quot;math inline&quot;&gt;\(r_2\)&lt;/span&gt;, and recall that &lt;code&gt;order&lt;/code&gt;
of a permutation is its inverse.&lt;/p&gt;
&lt;p&gt;Then &lt;span class=&quot;math inline&quot;&gt;\(y\)&lt;/span&gt; is &lt;span
class=&quot;math inline&quot;&gt;\(r_1\)&lt;/span&gt;, &lt;span
class=&quot;math inline&quot;&gt;\(x\)&lt;/span&gt; is &lt;span
class=&quot;math inline&quot;&gt;\(r_2^{-1}\)&lt;/span&gt;, and &lt;code&gt;order(s)&lt;/code&gt;
is&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;math display&quot;&gt;\[
s^{-1} = (xy)^{-1} = (r_2^{-1} r_1)^{-1} = r_1^{-1} r_2.
\]&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Which, when translated back to R, corresponds to the permutation&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb11&quot;&gt;&lt;pre class=&quot;sourceCode r&quot;&gt;&lt;code class=&quot;sourceCode r&quot;&gt;&lt;span id=&quot;cb11-1&quot;&gt;&lt;a href=&quot;#cb11-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;fu&quot;&gt;order&lt;/span&gt;(&lt;span class=&quot;fu&quot;&gt;rank&lt;/span&gt;(&lt;span class=&quot;fu&quot;&gt;names&lt;/span&gt;(v)))[&lt;span class=&quot;fu&quot;&gt;rank&lt;/span&gt;(month.abb)]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Can we also simplify &lt;code&gt;order(rank(names(v)))&lt;/code&gt;? You may
remember that &lt;code&gt;order&lt;/code&gt; and &lt;code&gt;rank&lt;/code&gt; are inverse of
each other and cancel them out. That would be a mistake. For any
&lt;code&gt;a&lt;/code&gt; (without duplicate elements), &lt;code&gt;order(a)&lt;/code&gt; and
&lt;code&gt;rank(a)&lt;/code&gt; are inverse &lt;em&gt;permutations&lt;/em&gt;
(&lt;code&gt;order(a)[rank(a)] == 1:length(a)&lt;/code&gt;); however,
&lt;code&gt;order&lt;/code&gt; and &lt;code&gt;rank&lt;/code&gt; are not inverse
&lt;em&gt;functions&lt;/em&gt;. It turns out that &lt;code&gt;order(rank(a))&lt;/code&gt; is
simply &lt;code&gt;order(a)&lt;/code&gt;, because &lt;code&gt;rank&lt;/code&gt; preserves the
order of the elements.&lt;/p&gt;
&lt;p&gt;Our final version is therefore&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb12&quot;&gt;&lt;pre class=&quot;sourceCode r&quot;&gt;&lt;code class=&quot;sourceCode r&quot;&gt;&lt;span id=&quot;cb12-1&quot;&gt;&lt;a href=&quot;#cb12-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;v[&lt;span class=&quot;fu&quot;&gt;order&lt;/span&gt;(&lt;span class=&quot;fu&quot;&gt;names&lt;/span&gt;(v))[&lt;span class=&quot;fu&quot;&gt;rank&lt;/span&gt;(month.abb)]]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;One might arrive at this result via an easier route, perhaps
observing that &lt;code&gt;v[order(names(v))]&lt;/code&gt; gives the alphabetically
sorted vector and &lt;code&gt;[rank(month.abb)]&lt;/code&gt; then restores the
chronological order, but it may be less obvious in more complicated
problems.&lt;/p&gt;
&lt;p&gt;Also, as I show in &lt;a
href=&quot;/articles/2016-03-19-rank-vs-order-r&quot;&gt;rank vs. order&lt;/a&gt;, if you
do this by trial and error and use small vectors to test your code, you
can easily arrive at something that looks right but isn’t. Let’s say
your data had only 4 months worth of data:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;set.seed(2)
month.abb &amp;lt;- month.abb[1:4]
v &amp;lt;- rpois(4, 50)
names(v) &amp;lt;- sample(month.abb)
v&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Jan Mar Apr Feb 
 43  43  42  50 &lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then this may look like the right solution (it’s not!):&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb15&quot;&gt;&lt;pre class=&quot;sourceCode r&quot;&gt;&lt;code class=&quot;sourceCode r&quot;&gt;&lt;span id=&quot;cb15-1&quot;&gt;&lt;a href=&quot;#cb15-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;v[&lt;span class=&quot;fu&quot;&gt;rank&lt;/span&gt;(&lt;span class=&quot;fu&quot;&gt;names&lt;/span&gt;(v))[&lt;span class=&quot;fu&quot;&gt;rank&lt;/span&gt;(month.abb)]]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;pre&gt;&lt;code&gt;Jan Feb Mar Apr 
 43  50  43  42 &lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So here’s how I recommend to approach such rearrangement
problems:&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;Start with &lt;code&gt;v[order(s)]&lt;/code&gt;, transforming the problem into
“where do I send the &lt;code&gt;i&lt;/code&gt;th element”&lt;/li&gt;
&lt;li&gt;Find or derive &lt;code&gt;s&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Optionally, simplify &lt;code&gt;order(s)&lt;/code&gt; using the algebra of
permutations&lt;/li&gt;
&lt;/ol&gt;
</description>
                        <pubDate>Sat, 18 Nov 2017 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2017-11-18-sort-in-given-order</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2017-11-18-sort-in-given-order.html</guid>
                </item>
        
                <item>
                        <title>Estimate program run time</title>
                        <description>&lt;p&gt;Programs used in bioinformatics vary a lot in how efficient their
algorithms and implementations are. Different programs may take from
minutes to years on the same data set.&lt;/p&gt;
&lt;p&gt;As a bioinformatician, you must have some idea about how long the
program will run. If the estimated time is too high, you may request
more resources (more and faster computers) or even decide not to run it
at all, rather than keep it running for two weeks and then kill it
without getting any results.&lt;/p&gt;
&lt;p&gt;You can estimate the run time of a program in three steps:&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;Collect the data&lt;/li&gt;
&lt;li&gt;Build a model&lt;/li&gt;
&lt;li&gt;Extrapolate&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;In this article, I will demonstrate this technique on a simple
example: estimate how long it takes bowtie2 to index the third human
chromosome.&lt;/p&gt;
&lt;h2 id=&quot;collect-the-data&quot;&gt;Collect the data&lt;/h2&gt;
&lt;p&gt;First, we download and unpack the chromosome’s nucleotide
sequence:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% wget ftp://ftp.ncbi.nih.gov/genomes/H_sapiens/CHR_03/hs_ref_GRCh38.p7_chr3.fa.gz
% gunzip hs_ref_GRCh38.p7_chr3.fa.gz&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In order to collect some data, we need to run the program. But if we
run the program on the full data set, it may take too long to complete —
the very problem we are trying to avoid.&lt;/p&gt;
&lt;p&gt;Therefore, we run the program on small subsets of the whole data set.
For instance, if we are working with many short sequences of similar
lengths, we may generate files consisting of the first &lt;span
class=&quot;math inline&quot;&gt;\(n\)&lt;/span&gt; sequences, as I explain &lt;a
href=&quot;/articles/2016-08-23-fasta-first-n-sequences&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;In our example, however, we have a few very long sequences, so we
will use the following awk script (which we’ll put in the file
&lt;code&gt;head_fasta.awk&lt;/code&gt;) to extract the first &lt;code&gt;limit&lt;/code&gt;
nucleotides:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb2&quot;&gt;&lt;pre
class=&quot;sourceCode awk&quot;&gt;&lt;code class=&quot;sourceCode awk&quot;&gt;&lt;span id=&quot;cb2-1&quot;&gt;&lt;a href=&quot;#cb2-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;/^&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;ot&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-2&quot;&gt;&lt;a href=&quot;#cb2-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-3&quot;&gt;&lt;a href=&quot;#cb2-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-4&quot;&gt;&lt;a href=&quot;#cb2-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-5&quot;&gt;&lt;a href=&quot;#cb2-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-6&quot;&gt;&lt;a href=&quot;#cb2-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;cf&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;((&lt;/span&gt;l&lt;span class=&quot;op&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;length&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dt&quot;&gt;$0&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;&amp;lt;&lt;/span&gt; limit&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-7&quot;&gt;&lt;a href=&quot;#cb2-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;kw&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-8&quot;&gt;&lt;a href=&quot;#cb2-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    limit &lt;span class=&quot;op&quot;&gt;-=&lt;/span&gt; l&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-9&quot;&gt;&lt;a href=&quot;#cb2-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;cf&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-10&quot;&gt;&lt;a href=&quot;#cb2-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;kw&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;substr&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dt&quot;&gt;$0&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; limit&lt;span class=&quot;op&quot;&gt;));&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-11&quot;&gt;&lt;a href=&quot;#cb2-11&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;cf&quot;&gt;exit&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-12&quot;&gt;&lt;a href=&quot;#cb2-12&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-13&quot;&gt;&lt;a href=&quot;#cb2-13&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Next, we write a shell script (&lt;code&gt;bench.sh&lt;/code&gt;) that will try
several numbers of nucleotides, generate a file of that size, run
&lt;code&gt;bowtie2-build&lt;/code&gt;, and record the time it took to complete.&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb3&quot;&gt;&lt;pre
class=&quot;sourceCode bash&quot;&gt;&lt;code class=&quot;sourceCode bash&quot;&gt;&lt;span id=&quot;cb3-1&quot;&gt;&lt;a href=&quot;#cb3-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;co&quot;&gt;#!/bin/bash&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-2&quot;&gt;&lt;a href=&quot;#cb3-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;co&quot;&gt;# We rely on bash to get custom-formatted &amp;#39;time&amp;#39; output.&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-3&quot;&gt;&lt;a href=&quot;#cb3-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;co&quot;&gt;# Otherwise, this script should be portable across shells.&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-4&quot;&gt;&lt;a href=&quot;#cb3-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-5&quot;&gt;&lt;a href=&quot;#cb3-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;co&quot;&gt;# change the format of &amp;#39;time&amp;#39; output to be the number of wall-clock seconds&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-6&quot;&gt;&lt;a href=&quot;#cb3-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;va&quot;&gt;TIMEFORMAT&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;st&quot;&gt;&amp;#39;%R&amp;#39;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-7&quot;&gt;&lt;a href=&quot;#cb3-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-8&quot;&gt;&lt;a href=&quot;#cb3-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;co&quot;&gt;# Print the csv header. &amp;#39;n&amp;#39; stands for the number of nucleotides, &amp;#39;t&amp;#39; stands for&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-9&quot;&gt;&lt;a href=&quot;#cb3-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;co&quot;&gt;# run time in seconds.&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-10&quot;&gt;&lt;a href=&quot;#cb3-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;bu&quot;&gt;printf&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;quot;n,t\n&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-11&quot;&gt;&lt;a href=&quot;#cb3-11&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-12&quot;&gt;&lt;a href=&quot;#cb3-12&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;co&quot;&gt;# iterate over 1M, 2M, ..., 10M nucleotides&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-13&quot;&gt;&lt;a href=&quot;#cb3-13&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;cf&quot;&gt;for&lt;/span&gt; n &lt;span class=&quot;kw&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;seq&lt;/span&gt; 1000000 1000000 10000000&lt;span class=&quot;kw&quot;&gt;`&lt;/span&gt; &lt;span class=&quot;co&quot;&gt;# start, step, end&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-14&quot;&gt;&lt;a href=&quot;#cb3-14&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;cf&quot;&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-15&quot;&gt;&lt;a href=&quot;#cb3-15&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;co&quot;&gt;# extract the first n nucleotides&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-16&quot;&gt;&lt;a href=&quot;#cb3-16&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;fu&quot;&gt;awk&lt;/span&gt; &lt;span class=&quot;at&quot;&gt;-v&lt;/span&gt; limit=&lt;span class=&quot;st&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;va&quot;&gt;$n&lt;/span&gt;&lt;span class=&quot;st&quot;&gt;&amp;quot;&lt;/span&gt; &lt;span class=&quot;at&quot;&gt;-f&lt;/span&gt; head_fasta.awk hs_ref_GRCh38.p7_chr3.fa &lt;span class=&quot;op&quot;&gt;&amp;gt;&lt;/span&gt; sample.fa&lt;/span&gt;
&lt;span id=&quot;cb3-17&quot;&gt;&lt;a href=&quot;#cb3-17&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;co&quot;&gt;# run bowtie2-build, noting the time&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-18&quot;&gt;&lt;a href=&quot;#cb3-18&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;co&quot;&gt;# ignore the bowtie&amp;#39;s output, and capture time&amp;#39;s output from stderr&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-19&quot;&gt;&lt;a href=&quot;#cb3-19&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;va&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;va&quot;&gt;$(&lt;/span&gt;&lt;span class=&quot;bu&quot;&gt;time&lt;/span&gt; &lt;span class=&quot;er&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ex&quot;&gt;bowtie2-build&lt;/span&gt; &lt;span class=&quot;at&quot;&gt;--noauto&lt;/span&gt; &lt;span class=&quot;at&quot;&gt;-f&lt;/span&gt; sample.fa sample &lt;span class=&quot;op&quot;&gt;&amp;gt;&lt;/span&gt;/dev/null &lt;span class=&quot;dv&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;&amp;gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;kw&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;&amp;gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;va&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-20&quot;&gt;&lt;a href=&quot;#cb3-20&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;co&quot;&gt;# print the csv row&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-21&quot;&gt;&lt;a href=&quot;#cb3-21&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;bu&quot;&gt;printf&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;quot;%d,%f\n&amp;quot;&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;va&quot;&gt;$n&lt;/span&gt;&lt;span class=&quot;st&quot;&gt;&amp;quot;&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;va&quot;&gt;$t&lt;/span&gt;&lt;span class=&quot;st&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-22&quot;&gt;&lt;a href=&quot;#cb3-22&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;cf&quot;&gt;done&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;There are a few things you should take into account when choosing the
range of values for &lt;span class=&quot;math inline&quot;&gt;\(n\)&lt;/span&gt;:&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;Obviously, the values shouldn’t be too high, so that data gathering
doesn’t take too long.&lt;/li&gt;
&lt;li&gt;The values also shouldn’t be too low; otherwise, the measurements
will be noisy and dominated by the fixed costs like program start time.
I usually try to come up with a range for which the first (fastest)
iteration completes in about a second.&lt;/li&gt;
&lt;li&gt;The range of values shouldn’t be too narrow compared to the values
themselves. This is so that any non-linear behavior can show itself. For
instance, the width of range &lt;span class=&quot;math inline&quot;&gt;\(101, 102,
\ldots, 110\)&lt;/span&gt; is &lt;span class=&quot;math inline&quot;&gt;\(110-101=9\)&lt;/span&gt;,
which is less than &lt;span class=&quot;math inline&quot;&gt;\(10\%\)&lt;/span&gt; compared to
the values themselves. Instead, I usually pick the range &lt;span
class=&quot;math inline&quot;&gt;\(n, 2n, \ldots, 10n\)&lt;/span&gt;, whose width is nine
times bigger than the smallest value.&lt;/li&gt;
&lt;li&gt;The number of values shouldn’t be too low, so that a regression
model can be fit. Ten is a good starting value.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The script will produce the output in the csv format; we use
&lt;code&gt;tee&lt;/code&gt; to look at it and write it to the file:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% ./bench.sh | tee time.csv&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here’s the output I got on my laptop:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb5&quot;&gt;&lt;pre
class=&quot;sourceCode bash&quot;&gt;&lt;code class=&quot;sourceCode bash&quot;&gt;&lt;span id=&quot;cb5-1&quot;&gt;&lt;a href=&quot;#cb5-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ex&quot;&gt;n,t&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-2&quot;&gt;&lt;a href=&quot;#cb5-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ex&quot;&gt;1000000,0.718000&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-3&quot;&gt;&lt;a href=&quot;#cb5-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ex&quot;&gt;2000000,1.439000&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-4&quot;&gt;&lt;a href=&quot;#cb5-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ex&quot;&gt;3000000,1.827000&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-5&quot;&gt;&lt;a href=&quot;#cb5-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ex&quot;&gt;4000000,3.115000&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-6&quot;&gt;&lt;a href=&quot;#cb5-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ex&quot;&gt;5000000,3.235000&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-7&quot;&gt;&lt;a href=&quot;#cb5-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ex&quot;&gt;6000000,4.390000&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-8&quot;&gt;&lt;a href=&quot;#cb5-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ex&quot;&gt;7000000,5.248000&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-9&quot;&gt;&lt;a href=&quot;#cb5-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ex&quot;&gt;8000000,7.153000&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-10&quot;&gt;&lt;a href=&quot;#cb5-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ex&quot;&gt;9000000,7.065000&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-11&quot;&gt;&lt;a href=&quot;#cb5-11&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ex&quot;&gt;10000000,8.664000&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;build-the-model&quot;&gt;Build the model&lt;/h2&gt;
&lt;p&gt;Let’s plot our data points. We do this to see how the run time grows
with &lt;span class=&quot;math inline&quot;&gt;\(n\)&lt;/span&gt;. Most tools designed to work
with big data sets will run in a linear or almost linear time, but it’s
better to check.&lt;/p&gt;
&lt;p&gt;To load and plot the data, we run the following R code:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb6&quot;&gt;&lt;pre class=&quot;sourceCode r&quot;&gt;&lt;code class=&quot;sourceCode r&quot;&gt;&lt;span id=&quot;cb6-1&quot;&gt;&lt;a href=&quot;#cb6-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;fu&quot;&gt;library&lt;/span&gt;(readr)&lt;/span&gt;
&lt;span id=&quot;cb6-2&quot;&gt;&lt;a href=&quot;#cb6-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;fu&quot;&gt;library&lt;/span&gt;(ggplot2)&lt;/span&gt;
&lt;span id=&quot;cb6-3&quot;&gt;&lt;a href=&quot;#cb6-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-4&quot;&gt;&lt;a href=&quot;#cb6-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;time &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;read_csv&lt;/span&gt;(&lt;span class=&quot;st&quot;&gt;&amp;quot;time.csv&amp;quot;&lt;/span&gt;)&lt;/span&gt;
&lt;span id=&quot;cb6-5&quot;&gt;&lt;a href=&quot;#cb6-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;fu&quot;&gt;ggplot&lt;/span&gt;(time, &lt;span class=&quot;fu&quot;&gt;aes&lt;/span&gt;(n,t)) &lt;span class=&quot;sc&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;geom_point&lt;/span&gt;() &lt;span class=&quot;sc&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;geom_smooth&lt;/span&gt;(&lt;span class=&quot;at&quot;&gt;method=&lt;/span&gt;&lt;span class=&quot;st&quot;&gt;&amp;quot;lm&amp;quot;&lt;/span&gt;,&lt;span class=&quot;at&quot;&gt;se=&lt;/span&gt;F)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div style=&quot;max-width: 600px; margin: auto;&quot;&gt;
&lt;p&gt;&lt;img src=&quot;/img/runtime.svg&quot; /&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;The blue line is the linear regression line. The fact that the middle
points are below the regression line is a sign of a faster-than-linear
growth. But the non-linearity is too subtle to be quadratic; so it’s
probably &lt;span class=&quot;math inline&quot;&gt;\(O(n\log n)\)&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;To build a model with correlated predictors (&lt;span
class=&quot;math inline&quot;&gt;\(n\)&lt;/span&gt; and &lt;span class=&quot;math inline&quot;&gt;\(n\log
n\)&lt;/span&gt; in this case), it’s better to have more data. Let’s rerun our
benchmark script, &lt;code&gt;bench.sh&lt;/code&gt;, with a smaller step size of
100000 and tee the output to &lt;code&gt;time2.csv&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Now we fit the model&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;math display&quot;&gt;\[t = a + b\cdot n + c\cdot n\log
n\]&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;and plot it along the data points. As a rule of thumb, if you include
higher-order terms (like &lt;span class=&quot;math inline&quot;&gt;\(n\log n\)&lt;/span&gt; or
&lt;span class=&quot;math inline&quot;&gt;\(n^2\)&lt;/span&gt;), include all lower-order terms
(like &lt;span class=&quot;math inline&quot;&gt;\(n\)&lt;/span&gt;) as well. Note that
&lt;code&gt;lm&lt;/code&gt; adds the intercept term &lt;span
class=&quot;math inline&quot;&gt;\(a\)&lt;/span&gt; automatically.&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb7&quot;&gt;&lt;pre class=&quot;sourceCode r&quot;&gt;&lt;code class=&quot;sourceCode r&quot;&gt;&lt;span id=&quot;cb7-1&quot;&gt;&lt;a href=&quot;#cb7-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;fu&quot;&gt;library&lt;/span&gt;(dplyr)&lt;/span&gt;
&lt;span id=&quot;cb7-2&quot;&gt;&lt;a href=&quot;#cb7-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;time &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;read_csv&lt;/span&gt;(&lt;span class=&quot;st&quot;&gt;&amp;quot;time2.csv&amp;quot;&lt;/span&gt;)&lt;/span&gt;
&lt;span id=&quot;cb7-3&quot;&gt;&lt;a href=&quot;#cb7-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;nlm &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;lm&lt;/span&gt;(t &lt;span class=&quot;sc&quot;&gt;~&lt;/span&gt; n &lt;span class=&quot;sc&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;I&lt;/span&gt;(n&lt;span class=&quot;sc&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;log&lt;/span&gt;(n)), &lt;span class=&quot;at&quot;&gt;data=&lt;/span&gt;time)&lt;/span&gt;
&lt;span id=&quot;cb7-4&quot;&gt;&lt;a href=&quot;#cb7-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;time &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;mutate&lt;/span&gt;(time, &lt;span class=&quot;at&quot;&gt;model=&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;predict&lt;/span&gt;(nlm))&lt;/span&gt;
&lt;span id=&quot;cb7-5&quot;&gt;&lt;a href=&quot;#cb7-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb7-6&quot;&gt;&lt;a href=&quot;#cb7-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;fu&quot;&gt;ggplot&lt;/span&gt;(time) &lt;span class=&quot;sc&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;geom_point&lt;/span&gt;(&lt;span class=&quot;fu&quot;&gt;aes&lt;/span&gt;(n,t)) &lt;span class=&quot;sc&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;geom_line&lt;/span&gt;(&lt;span class=&quot;fu&quot;&gt;aes&lt;/span&gt;(n,model), &lt;span class=&quot;at&quot;&gt;color=&lt;/span&gt;&lt;span class=&quot;st&quot;&gt;&amp;quot;blue&amp;quot;&lt;/span&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div style=&quot;max-width: 600px; margin: auto;&quot;&gt;
&lt;p&gt;&lt;img src=&quot;/img/runtime2.svg&quot; /&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;The model with an &lt;span class=&quot;math inline&quot;&gt;\(n\log n\)&lt;/span&gt; term
gives a more realistic fit, so we’ll stick with it.&lt;/p&gt;
&lt;h2 id=&quot;extrapolate&quot;&gt;Extrapolate&lt;/h2&gt;
&lt;p&gt;Let’s find out how many nucleotides are in the whole chromosome:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% awk &amp;#39;/^[^&amp;gt;]/{n+=length($0)} END{print(n)}&amp;#39; hs_ref_GRCh38.p7_chr3.fa
202786747&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now we simply plug this number into our R model:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb9&quot;&gt;&lt;pre class=&quot;sourceCode r&quot;&gt;&lt;code class=&quot;sourceCode r&quot;&gt;&lt;span id=&quot;cb9-1&quot;&gt;&lt;a href=&quot;#cb9-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;fu&quot;&gt;predict&lt;/span&gt;(nlm, &lt;span class=&quot;at&quot;&gt;newdata=&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;list&lt;/span&gt;(&lt;span class=&quot;at&quot;&gt;n=&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;202786747&lt;/span&gt;))&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;pre&gt;&lt;code&gt;332.2153&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So, our prediction is 332 seconds, or 5.5 minutes.&lt;/p&gt;
&lt;p&gt;To check this prediction, I actually left &lt;code&gt;bowtie2-build&lt;/code&gt;
running for a while. It completed in 350 seconds — within 5% of our
prediction!&lt;/p&gt;
&lt;p&gt;On the other hand, if we went with the linear model, our prediction
would have been 176 seconds — a severe underestimation by a factor of 2.
The model with &lt;span class=&quot;math inline&quot;&gt;\(n \log n\)&lt;/span&gt; but without
the linear term would have predicted 206 seconds — only somewhat better
than the linear model.&lt;/p&gt;
</description>
                        <pubDate>Thu, 09 Nov 2017 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2017-11-09-estimate-program-run-time</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2017-11-09-estimate-program-run-time.html</guid>
                </item>
        
                <item>
                        <title>Does correlation imply causation?</title>
                        <description>&lt;p&gt;In episode 55 of The Effort Report podcast, Roger Peng makes an
interesting observation: correlation implies causation all the time!
That’s how we know most of things in science, including that smoking
causes lung cancer.&lt;/p&gt;
&lt;iframe style=&quot;border: none&quot; src=&quot;//html5-player.libsyn.com/embed/episode/id/5757114/height/90/width/700/theme/custom/autonext/no/thumbnail/yes/autoplay/no/preload/no/no_addthis/no/direction/forward/render-playlist/no/custom-color/328f9b/&quot; height=&quot;90&quot; width=&quot;700&quot; scrolling=&quot;no&quot; allowfullscreen webkitallowfullscreen mozallowfullscreen oallowfullscreen msallowfullscreen&gt;
&lt;/iframe&gt;
&lt;p&gt;(around 00:37:30)&lt;/p&gt;
&lt;p&gt;Roger is not wrong, but the informal language makes his statement
ambiguous.&lt;/p&gt;
&lt;p&gt;In formal logic, we almost never say “A implies B” &lt;span
class=&quot;math inline&quot;&gt;\((A \Rightarrow B)\)&lt;/span&gt;, except as a shorthand
for something else.&lt;/p&gt;
&lt;p&gt;Instead, we say A implies B under a set of assumptions Γ, or&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;math display&quot;&gt;\[\Gamma \vdash A \Rightarrow
B.\]&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Therefore, the statement “A implies B” can be valid under some Γ and
invalid under others.&lt;/p&gt;
&lt;p&gt;When we say “correlation does not imply causation”, we implicitly
mean “without any additional assumptions”, that is,&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;math display&quot;&gt;\[\varnothing \nvdash \text{X correlates
with Y}\Rightarrow\text{X causes Y}.\]&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;But under a suitable set of &lt;em&gt;causal assumptions&lt;/em&gt; Γ,
correlation may very well imply causation, which is one way to interpret
Roger’s claim:&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;math display&quot;&gt;\[\Gamma \vdash \text{X correlates with
Y}\Rightarrow\text{X causes Y}.\]&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Elizabeth Matsui actually points to this difference when she says
“correlation does not &lt;em&gt;equal&lt;/em&gt; causation”.&lt;/p&gt;
&lt;p&gt;To learn about causal assumptions, read the excellent &lt;a
href=&quot;http://ftp.cs.ucla.edu/pub/stat_ser/r350.pdf&quot;&gt;overview of causal
inference&lt;/a&gt; by Judea Pearl or one of his many other works.&lt;/p&gt;
</description>
                        <pubDate>Thu, 28 Sep 2017 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2017-09-28-does-correlation-imply-causation</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2017-09-28-does-correlation-imply-causation.html</guid>
                </item>
        
                <item>
                        <title>How Booking.com manipulates you</title>
                        <description>&lt;p&gt;Many websites and applications these days are designed to trick you
into doing things that their creators want. Here are some examples from
&lt;a href=&quot;http://www.timewellspent.io/&quot;&gt;timewellspent.io&lt;/a&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;YouTube autoplays more videos to keep us from leaving.&lt;/li&gt;
&lt;li&gt;Instagram shows new likes one at a time, to keep us checking for
more.&lt;/li&gt;
&lt;li&gt;Facebook wants to show whatever keeps us scrolling.&lt;/li&gt;
&lt;li&gt;Snapchat turns conversations into streaks we don’t want to
lose.&lt;/li&gt;
&lt;li&gt;Our media turns events into breaking news to keep us watching.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;But one of the most manipulative websites I’ve ever come across is
Booking.com, the large hotel search &amp;amp; booking service.&lt;/p&gt;
&lt;p&gt;If you ever used Booking.com, you probably noticed (and hopefully
resisted!) some ways it nudges you to book whatever property you are
looking at:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/img/booking.com/screen1.png&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Let’s see what’s going on here.&lt;/p&gt;
&lt;h2 id=&quot;prices&quot;&gt;Prices&lt;/h2&gt;
&lt;p&gt;First, it tries to persuade you that the price is low. “Jackpot! This
is the cheapest price you’ve seen in London for your dates!” Of course
it is — this is literally the first price I am seeing for these days —
so that statement is &lt;a
href=&quot;https://en.wikipedia.org/wiki/Tautology_(logic)&quot;&gt;tautological&lt;/a&gt;.
&lt;strong&gt;The first price I see will automatically be the lowest I will
have seen, no matter how ridiculously high it’s going to be.&lt;/strong&gt;
The statement “This is the highest price you’ve seen in London for your
dates!” would be just as valid.&lt;/p&gt;
&lt;p&gt;Likewise, the struck-through prices are there to &lt;a
href=&quot;https://en.wikipedia.org/wiki/Anchoring&quot;&gt;anchor&lt;/a&gt; you and make
the actual price seem like a great deal. The struck-through US$175 is
before applying my 10% “genius” discount — ok, that’s fair. But where
does the US$189 come from? Let’s hover over the price to get an
explanation:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/img/booking.com/screen2.png&quot; /&gt;&lt;/p&gt;
&lt;p&gt;I imagine most people will feel intimidated by the complex
description, skip to the last sentence, and get the impression that “you
get the same room for a lower price compared to other check-in dates”.
(If this wasn’t the case, Booking.com’s marketing department would
change the wording to make it so.)&lt;/p&gt;
&lt;p&gt;But what is it actually saying? If there is only one room of this
type, then 90% of time there will be an appearance of a lucky deal.
&lt;strong&gt;What you should be reading is “If I choose this, I am not a
total loser”.&lt;/strong&gt; And if there are 3 comparable room types with
differential pricing, there is even less of a reason to feel good about
this — you’ve successfully avoided the worst 3% of the offerings.&lt;/p&gt;
&lt;h2 id=&quot;urgency&quot;&gt;Urgency&lt;/h2&gt;
&lt;p&gt;Another way Booking.com manipulates you is by conveying &lt;strong&gt;the
sense of urgency&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;“In high demand - only 3 rooms left on our site!”&lt;/p&gt;
&lt;p&gt;“33 other people looking now, according to our Booking.com travel
scientists” (what?)&lt;/p&gt;
&lt;p&gt;“Last chance! Only 1 room left on our site!”&lt;/p&gt;
&lt;p&gt;And just to prove they are not kidding, they will show you something
that you’ve missed already:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/img/booking.com/screen3.png&quot; /&gt;&lt;/p&gt;
&lt;p&gt;But my favorite one is this red badge:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/img/booking.com/screen4.png&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Although it cannot be seen on the screenshot, the badge doesn’t
appear right away when you open the page. Instead, &lt;strong&gt;it pops up
one or two seconds later, making it seem like a realtime
notification&lt;/strong&gt; — an impression reinforced by the alarm clock
icon. To be clear, it is not realtime, and there is no reason to delay
its display other than to trick you:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/img/booking.com/screen5.png&quot; /&gt;&lt;/p&gt;
&lt;p&gt;How much time has elapsed since the last booking doesn’t simply play
on our irrational emotions. This is a valuable piece of information that
can be used to estimate at what rate these rooms are being booked. By a
&lt;a
href=&quot;https://en.wikipedia.org/wiki/J._Richard_Gott#Copernicus_method_and_Doomsday_theory&quot;&gt;Gott&lt;/a&gt;-like
argument (see &lt;a
href=&quot;https://www.goodreads.com/book/show/32708206-algorithms-to-live-by&quot;&gt;Algorithms
to Live By&lt;/a&gt; for an excellent explanation), if the last booking was
made 4 hours ago, you can estimate that a room is booked about every 8
hours. Plenty of time to relax and compare your options. If, on the
other hand, the last booking happened just two seconds ago, you’d better
not waste another second before entering your credit card number.&lt;/p&gt;
&lt;p&gt;Kudos to Booking for at least providing the actual information in a
tooltip window (I wonder what regulations make them do that), but not
all users will hover to read it, and even then, something that you
experience (a badge popping up) will probably take precedence over what
you later read.&lt;/p&gt;
&lt;p&gt;The “Someone just booked this” badge does not just make you worry
that the room you are considering will soon be snatched; it also
reassures you. If other people are actively booking this property, it
must be good. Of course, the person who made a reservation 4 hours ago
has not yet visited the hotel and so probably has little more knowledge
than you. &lt;strong&gt;Their decision to book is probably to some extent
influenced by the same red badge.&lt;/strong&gt; This situation, where
everyone relies on everyone else to have accurate information, is also
well described in &lt;a
href=&quot;https://www.goodreads.com/book/show/32708206-algorithms-to-live-by&quot;&gt;Algorithms
to Live By&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;reviews&quot;&gt;Reviews&lt;/h2&gt;
&lt;p&gt;Instead of listening to people who have just booked the property but
have not yet visited it, we should turn to those who have been there,
right? That’s what reviews are for!&lt;/p&gt;
&lt;p&gt;But Booking.com managed to game the reviews, too. There are quite a
few crappy hotels out there, especially on the cheaper end of the
spectrum. These are the hotels you and I would want to avoid, but if we
did, Booking would not make money on them.&lt;/p&gt;
&lt;p&gt;An extreme example is the hotel I’m currently staying at, New Union.
From its Booking.com page you wouldn’t think there’s anything wrong with
it, would you?&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/img/booking.com/screen6.png&quot; /&gt;&lt;/p&gt;
&lt;p&gt;If you spend enough time perusing that page, you’ll eventually
stumble upon the “fine print”:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/img/booking.com/screen7.png&quot; /&gt;&lt;/p&gt;
&lt;p&gt;“noise may be heard whilst the bar is open” is an understatement; the
music is so loud that the floor in my room shakes very perceptibly, and
the bar is open until late at night/early in the morning. And why is
this warning hidden in the fine print instead of being a big red fucking
badge?&lt;/p&gt;
&lt;p&gt;To be fair, this is more of the hotel’s fault than Booking’s. Also, I
should have read the fine print. Or the reviews. But wait, I’ve read the
reviews:&lt;/p&gt;
&lt;figure&gt;
&lt;img src=&quot;/img/booking.com/screen8.png&quot; /&gt; &lt;img
src=&quot;/img/booking.com/screen9.png&quot; /&gt;
&lt;/figure&gt;
&lt;p&gt;What I didn’t realize skimming an overloaded webpage was that
&lt;strong&gt;the reviews displayed on the main page had been
cherry-picked&lt;/strong&gt;. The full list of reviews is available from a
separate page, e.g.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/img/booking.com/screen10.png&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/img/booking.com/screen11.png&quot; /&gt;&lt;/p&gt;
&lt;h2 id=&quot;ratings&quot;&gt;Ratings&lt;/h2&gt;
&lt;p&gt;Notice something interesting here: the first, moderately negative
review, gives the place a rating of 7 out of 10, and the second review,
probably as negative as it gets, gives it almost a 6. As a result, the
overall rating of the property is high (7.6), and even the distribution
of ratings does not look alarming:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/img/booking.com/screen12.png&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Unlike IMDB or Amazon, where you simply give a movie or product a
number of stars, when you rate your stay on Booking.com, you evaluate it
on several factors: location, cleanliness, facilities etc.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/img/booking.com/screen13.png&quot; /&gt;&lt;/p&gt;
&lt;p&gt;But Booking.com doesn’t present individual ratings; it presents the
average (like 7.1 or 5.8) and the average of averages (the overall
rating of a property). It is unlikely that all factors will be bad
simultaneously, but a problem in one of them may easily ruin your trip.
&lt;strong&gt;A great location will not compensate for sleepless nights, but
Booking.com thinks otherwise.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Baran Toppare and &lt;span class=&quot;citation&quot;
data-cites=&quot;tqenn&quot;&gt;@tqenn&lt;/span&gt; both pointed out another way in which
Booking.com ratings are inflated:&lt;/p&gt;
&lt;blockquote class=&quot;twitter-tweet&quot; data-lang=&quot;en&quot;&gt;
&lt;p lang=&quot;en&quot; dir=&quot;ltr&quot;&gt;
You missed the fact their reviews are not on a 0-10 scale, but 2.5-10.
Every review score is intentionally inflated. Try reviewing &amp;amp; see.
&lt;/p&gt;
— Tqenn (&lt;span class=&quot;citation&quot; data-cites=&quot;tqenn&quot;&gt;@tqenn&lt;/span&gt;)
&lt;a href=&quot;https://twitter.com/tqenn/status/910981208774934528&quot;&gt;September
21, 2017&lt;/a&gt;
&lt;/blockquote&gt;
&lt;p&gt;(To explain Booking’s system, each factor’s rating is on the scale
{2.5, 5, 7.5, 10}, and the combined rating is the arithmetic mean of all
factors.)&lt;/p&gt;
&lt;p&gt;I agree, except ratings on the internet are almost never 0-based. The
number of stars usually goes from 1 to 5. But if they really wanted a
4-point scale culminating at 10, they could have picked the scale {1, 4,
7, 10}. So yes, this is another way in which Booking.com artificially
increases hotel ratings.&lt;/p&gt;
&lt;h2 id=&quot;what-to-do-with-all-of-this&quot;&gt;What to do with all of this&lt;/h2&gt;
&lt;p&gt;Frankly, I don’t think I am going to stop using Booking.com. I am not
aware of any other service with a comparable number of properties and
reviews.&lt;/p&gt;
&lt;p&gt;Instead, we need to be aware of all the ways Booking is trying to
screw us over and try to counter them:&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;Ignore urgency-provoking red text and anchoring struck-through
prices.&lt;/li&gt;
&lt;li&gt;Do not rely on the magnitude of the ratings. I think it is still
fine to use them as a sorting criterion.&lt;/li&gt;
&lt;li&gt;Do not read the cherry-picked reviews on the main page. Go to the
review page (“Our guests’ experiences”) and sort the reviews from newest
to oldest, to get an up-to-date and hopefully unbiased selection.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;As I learned from several commenters on &lt;a
href=&quot;https://news.ycombinator.com/item?id=15297915&quot;&gt;Hacker News&lt;/a&gt;,
these manipulative tricks are called “dark patterns”, and they are
catalogued over at &lt;a
href=&quot;https://darkpatterns.org/&quot;&gt;darkpatterns.org&lt;/a&gt;.&lt;/p&gt;
</description>
                        <pubDate>Sun, 17 Sep 2017 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2017-09-17-booking-com-manipulation</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2017-09-17-booking-com-manipulation.html</guid>
                </item>
        
                <item>
                        <title>Understanding Asymmetric Numeral Systems</title>
                        <description>&lt;p&gt;Apparently, &lt;a
href=&quot;https://www.reddit.com/r/programming/comments/6h08z5/google_is_currently_trying_to_patent_video/&quot;&gt;Google
is trying to patent (an application of) Asymmetric Numeral Systems&lt;/a&gt;,
so I spent some time today learning what it is.&lt;/p&gt;
&lt;p&gt;In its essense lies a simple and beautiful idea.&lt;/p&gt;
&lt;p&gt;&lt;img
src=&quot;https://dropboxtechblog.files.wordpress.com/2016/06/silicon-valley.jpg?w=650&amp;amp;h=380&quot; /&gt;&lt;/p&gt;
&lt;p&gt;ANS is a lossless compression algorithm. Its input is a list of
symbols from some finite set. Its output is a positive integer. Each
symbol &lt;span class=&quot;math inline&quot;&gt;\(s\)&lt;/span&gt; has a fixed known
probability &lt;span class=&quot;math inline&quot;&gt;\(p_s\)&lt;/span&gt; of occurring in the
list. The algorithm tries to assign each list a unique integer so that
the more probable lists get smaller integers.&lt;/p&gt;
&lt;p&gt;If we ignore the compression part (assigning smaller integers to more
probable inputs), the encoding could be done as follows: convert each
symbol to a number from &lt;span class=&quot;math inline&quot;&gt;\(0\)&lt;/span&gt; to &lt;span
class=&quot;math inline&quot;&gt;\(B-1\)&lt;/span&gt; (where &lt;span
class=&quot;math inline&quot;&gt;\(B\)&lt;/span&gt; is the number of symbols), add a
leading 1 to avoid ambiguities caused by leading zeros, and interpret
the list as an integer written in a base-&lt;span
class=&quot;math inline&quot;&gt;\(B\)&lt;/span&gt; positional system.&lt;/p&gt;
&lt;p&gt;This encoding process is an iterative/recursive algorithm:&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;Start with the number 1;&lt;/li&gt;
&lt;li&gt;If the current number is &lt;span class=&quot;math inline&quot;&gt;\(n\)&lt;/span&gt;, and
the incoming symbol correspond to a number &lt;span
class=&quot;math inline&quot;&gt;\(s\)&lt;/span&gt;, update the number to be &lt;span
class=&quot;math inline&quot;&gt;\(s + n\cdot B\)&lt;/span&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The decoding process is a corecursive algorithm:&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;Start with the number that we are decoding;&lt;/li&gt;
&lt;li&gt;Split the current number &lt;span class=&quot;math inline&quot;&gt;\(n\)&lt;/span&gt; into
the quotient and remainder modulo &lt;span
class=&quot;math inline&quot;&gt;\(B\)&lt;/span&gt;;&lt;/li&gt;
&lt;li&gt;Emit the remainder and continue decoding the quotient;&lt;/li&gt;
&lt;li&gt;Stop when the current number reaches 1.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;(The decoding is LIFO: the first decoded element will be the last
encoded element.)&lt;/p&gt;
&lt;p&gt;This encoding scheme relies on the standard isomorphism between the
sets &lt;span class=&quot;math inline&quot;&gt;\(\{0,\ldots,B-1\}\times \mathbb{Z}_{\geq
1}\)&lt;/span&gt; and &lt;span class=&quot;math inline&quot;&gt;\(\mathbb{Z}_{\geq
B}\)&lt;/span&gt;, established by the functions&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;math display&quot;&gt;\[f(s,n) = s + n\cdot B;\]&lt;/span&gt; &lt;span
class=&quot;math display&quot;&gt;\[g(n) = (n \bmod B, [n/B]).\]&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;(The peculiar domain and codomain of this isomorphism are chosen so
that we have &lt;span class=&quot;math inline&quot;&gt;\(\forall n,s.\;f(s,n) &amp;gt;
n\)&lt;/span&gt;; this ensures that the decoding process doesn’t get
stuck.)&lt;/p&gt;
&lt;p&gt;We can represent this in Haskell as&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb1&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb1-1&quot;&gt;&lt;a href=&quot;#cb1-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;{-# LANGUAGE ScopedTypeVariables, TypeApplications,&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-2&quot;&gt;&lt;a href=&quot;#cb1-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;             NamedFieldPuns, AllowAmbiguousTypes #-}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-3&quot;&gt;&lt;a href=&quot;#cb1-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-4&quot;&gt;&lt;a href=&quot;#cb1-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Data.Ord&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-5&quot;&gt;&lt;a href=&quot;#cb1-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Data.List&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-6&quot;&gt;&lt;a href=&quot;#cb1-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Numeric.Natural&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-7&quot;&gt;&lt;a href=&quot;#cb1-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-8&quot;&gt;&lt;a href=&quot;#cb1-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Iso&lt;/span&gt; a b &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Iso&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-9&quot;&gt;&lt;a href=&quot;#cb1-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  {&lt;span class=&quot;ot&quot;&gt; to ::&lt;/span&gt; a &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; b&lt;/span&gt;
&lt;span id=&quot;cb1-10&quot;&gt;&lt;a href=&quot;#cb1-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  ,&lt;span class=&quot;ot&quot;&gt; from ::&lt;/span&gt; b &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; a&lt;/span&gt;
&lt;span id=&quot;cb1-11&quot;&gt;&lt;a href=&quot;#cb1-11&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  }&lt;/span&gt;
&lt;span id=&quot;cb1-12&quot;&gt;&lt;a href=&quot;#cb1-12&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-13&quot;&gt;&lt;a href=&quot;#cb1-13&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;encode ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Iso&lt;/span&gt; (s, &lt;span class=&quot;dt&quot;&gt;Natural&lt;/span&gt;) &lt;span class=&quot;dt&quot;&gt;Natural&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; [s] &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Natural&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-14&quot;&gt;&lt;a href=&quot;#cb1-14&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;encode &lt;span class=&quot;dt&quot;&gt;Iso&lt;/span&gt;{to} &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; foldl&amp;#39; (\acc s &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; to (s, acc)) &lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-15&quot;&gt;&lt;a href=&quot;#cb1-15&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-16&quot;&gt;&lt;a href=&quot;#cb1-16&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;decode ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Iso&lt;/span&gt; (s, &lt;span class=&quot;dt&quot;&gt;Natural&lt;/span&gt;) &lt;span class=&quot;dt&quot;&gt;Natural&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Natural&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; [s]&lt;/span&gt;
&lt;span id=&quot;cb1-17&quot;&gt;&lt;a href=&quot;#cb1-17&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;decode &lt;span class=&quot;dt&quot;&gt;Iso&lt;/span&gt;{from} &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;reverse&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt; unfoldr&lt;/span&gt;
&lt;span id=&quot;cb1-18&quot;&gt;&lt;a href=&quot;#cb1-18&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  (\n &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-19&quot;&gt;&lt;a href=&quot;#cb1-19&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;kw&quot;&gt;if&lt;/span&gt; n &lt;span class=&quot;op&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-20&quot;&gt;&lt;a href=&quot;#cb1-20&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;kw&quot;&gt;then&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Nothing&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-21&quot;&gt;&lt;a href=&quot;#cb1-21&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;kw&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Just&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; from n&lt;/span&gt;
&lt;span id=&quot;cb1-22&quot;&gt;&lt;a href=&quot;#cb1-22&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  )&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;And the standard isomorphism which we used in the simple encoding
process is&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb2&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb2-1&quot;&gt;&lt;a href=&quot;#cb2-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;std_iso ::&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;forall&lt;/span&gt; s &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;Bounded&lt;/span&gt; s, &lt;span class=&quot;dt&quot;&gt;Enum&lt;/span&gt; s) &lt;span class=&quot;ot&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Iso&lt;/span&gt; (s, &lt;span class=&quot;dt&quot;&gt;Natural&lt;/span&gt;) &lt;span class=&quot;dt&quot;&gt;Natural&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-2&quot;&gt;&lt;a href=&quot;#cb2-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;std_iso &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Iso&lt;/span&gt; (\(s,n) &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; s2n s &lt;span class=&quot;op&quot;&gt;+&lt;/span&gt; base &lt;span class=&quot;op&quot;&gt;@&lt;/span&gt;s &lt;span class=&quot;op&quot;&gt;*&lt;/span&gt; n) (\n &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; (n2s &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; n &lt;span class=&quot;ot&quot;&gt;`mod`&lt;/span&gt; base &lt;span class=&quot;op&quot;&gt;@&lt;/span&gt;s, n &lt;span class=&quot;ot&quot;&gt;`div`&lt;/span&gt; base &lt;span class=&quot;op&quot;&gt;@&lt;/span&gt;s))&lt;/span&gt;
&lt;span id=&quot;cb2-3&quot;&gt;&lt;a href=&quot;#cb2-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-4&quot;&gt;&lt;a href=&quot;#cb2-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;s2n ::&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;forall&lt;/span&gt; s &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;Bounded&lt;/span&gt; s, &lt;span class=&quot;dt&quot;&gt;Enum&lt;/span&gt; s) &lt;span class=&quot;ot&quot;&gt;=&amp;gt;&lt;/span&gt; s &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Natural&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-5&quot;&gt;&lt;a href=&quot;#cb2-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;s2n s &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;fromIntegral&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-6&quot;&gt;&lt;a href=&quot;#cb2-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  ((&lt;span class=&quot;fu&quot;&gt;fromIntegral&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;fromEnum&lt;/span&gt;)&lt;span class=&quot;ot&quot;&gt; s             ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Integer&lt;/span&gt;) &lt;span class=&quot;op&quot;&gt;-&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-7&quot;&gt;&lt;a href=&quot;#cb2-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  ((&lt;span class=&quot;fu&quot;&gt;fromIntegral&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;fromEnum&lt;/span&gt;) (&lt;span class=&quot;fu&quot;&gt;minBound&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;@&lt;/span&gt;s)&lt;span class=&quot;ot&quot;&gt; ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Integer&lt;/span&gt;)&lt;/span&gt;
&lt;span id=&quot;cb2-8&quot;&gt;&lt;a href=&quot;#cb2-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-9&quot;&gt;&lt;a href=&quot;#cb2-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;n2s ::&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;forall&lt;/span&gt; s &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;Bounded&lt;/span&gt; s, &lt;span class=&quot;dt&quot;&gt;Enum&lt;/span&gt; s) &lt;span class=&quot;ot&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Natural&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; s&lt;/span&gt;
&lt;span id=&quot;cb2-10&quot;&gt;&lt;a href=&quot;#cb2-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;n2s n &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;toEnum&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;fromIntegral&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-11&quot;&gt;&lt;a href=&quot;#cb2-11&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  (&lt;span class=&quot;fu&quot;&gt;fromIntegral&lt;/span&gt; n &lt;span class=&quot;op&quot;&gt;+&lt;/span&gt; (&lt;span class=&quot;fu&quot;&gt;fromIntegral&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;fromEnum&lt;/span&gt;) (&lt;span class=&quot;fu&quot;&gt;minBound&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;@&lt;/span&gt;s)&lt;span class=&quot;ot&quot;&gt; ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Integer&lt;/span&gt;)&lt;/span&gt;
&lt;span id=&quot;cb2-12&quot;&gt;&lt;a href=&quot;#cb2-12&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-13&quot;&gt;&lt;a href=&quot;#cb2-13&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;base ::&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;forall&lt;/span&gt; s &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;Bounded&lt;/span&gt; s, &lt;span class=&quot;dt&quot;&gt;Enum&lt;/span&gt; s) &lt;span class=&quot;ot&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Natural&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-14&quot;&gt;&lt;a href=&quot;#cb2-14&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;base &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; s2n (&lt;span class=&quot;fu&quot;&gt;maxBound&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;@&lt;/span&gt;s) &lt;span class=&quot;op&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;(The functions are more complicated than they have to be to support
symbol types like &lt;code&gt;Int&lt;/code&gt;. &lt;code&gt;Int&lt;/code&gt; does not start at 0
and is prone to overflow.)&lt;/p&gt;
&lt;p&gt;Let’s now turn to the general form of the isomorphism&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;math display&quot;&gt;\[f \colon \{0,\ldots,B-1\}\times
\mathbb{Z}_{\geq 1} \to \mathbb{Z}_{\geq \beta};\]&lt;/span&gt; &lt;span
class=&quot;math display&quot;&gt;\[g \colon \mathbb{Z}_{\geq \beta} \to
\{0,\ldots,B-1\}\times \mathbb{Z}_{\geq 1}.\]&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;(In general, &lt;span class=&quot;math inline&quot;&gt;\(\beta\)&lt;/span&gt;, the smallest
value of &lt;span class=&quot;math inline&quot;&gt;\(f\)&lt;/span&gt;, does not have to equal
&lt;span class=&quot;math inline&quot;&gt;\(B\)&lt;/span&gt;, the number of symbols.)&lt;/p&gt;
&lt;p&gt;If we know (or postulate) that the second component of &lt;span
class=&quot;math inline&quot;&gt;\(g\)&lt;/span&gt;, &lt;span class=&quot;math inline&quot;&gt;\(g_2\colon
\mathbb{Z}_{\geq \beta} \to \mathbb{Z}_{\geq 1}\)&lt;/span&gt;, is increasing,
then we can recover it from the first component, &lt;span
class=&quot;math inline&quot;&gt;\(g_1\colon \mathbb{Z}_{\geq \beta} \to
\{0,\ldots,B-1\}\)&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;Indeed, for a given &lt;span class=&quot;math inline&quot;&gt;\(s=g_1(n)\)&lt;/span&gt;,
&lt;span class=&quot;math inline&quot;&gt;\(g_2\)&lt;/span&gt; must be the unique increasing
isomorphism from &lt;span class=&quot;math display&quot;&gt;\[A_s = \{f(s,m)\mid
m\in\mathbb{Z}_{\geq 1}\} = \{n\mid n\in\mathbb{Z}_{\geq \beta}, g_1(n)
= s\}\]&lt;/span&gt; to &lt;span class=&quot;math inline&quot;&gt;\(\mathbb{Z}_{\geq
1}\)&lt;/span&gt;. To find &lt;span class=&quot;math inline&quot;&gt;\(g_2(n)\)&lt;/span&gt;, count
the number of elements in &lt;span class=&quot;math inline&quot;&gt;\(A_s\)&lt;/span&gt; that
are &lt;span class=&quot;math inline&quot;&gt;\(\leq n\)&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;Similarly, we can recover &lt;span class=&quot;math inline&quot;&gt;\(f\)&lt;/span&gt; from
&lt;span class=&quot;math inline&quot;&gt;\(g_1\)&lt;/span&gt;. To compute &lt;span
class=&quot;math inline&quot;&gt;\(f(s,n)\)&lt;/span&gt;, take &lt;span
class=&quot;math inline&quot;&gt;\(n\)&lt;/span&gt;th smallest number in &lt;span
class=&quot;math inline&quot;&gt;\(A_s\)&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;In Haskell:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb3&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb3-1&quot;&gt;&lt;a href=&quot;#cb3-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;ans_iso ::&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;forall&lt;/span&gt; s &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Eq&lt;/span&gt; s &lt;span class=&quot;ot&quot;&gt;=&amp;gt;&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;Natural&lt;/span&gt;, &lt;span class=&quot;dt&quot;&gt;Natural&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; s) &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Iso&lt;/span&gt; (s, &lt;span class=&quot;dt&quot;&gt;Natural&lt;/span&gt;) &lt;span class=&quot;dt&quot;&gt;Natural&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-2&quot;&gt;&lt;a href=&quot;#cb3-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;ans_iso (b, classify) &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Iso&lt;/span&gt;{to, from} &lt;span class=&quot;kw&quot;&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-3&quot;&gt;&lt;a href=&quot;#cb3-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;  to ::&lt;/span&gt; (s, &lt;span class=&quot;dt&quot;&gt;Natural&lt;/span&gt;) &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Natural&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-4&quot;&gt;&lt;a href=&quot;#cb3-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  to (s, n) &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; [ k &lt;span class=&quot;op&quot;&gt;|&lt;/span&gt; k &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; [b&lt;span class=&quot;op&quot;&gt;..&lt;/span&gt;], classify k &lt;span class=&quot;op&quot;&gt;==&lt;/span&gt; s ] &lt;span class=&quot;ot&quot;&gt;`genericIndex`&lt;/span&gt; (n&lt;span class=&quot;op&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;)&lt;/span&gt;
&lt;span id=&quot;cb3-5&quot;&gt;&lt;a href=&quot;#cb3-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-6&quot;&gt;&lt;a href=&quot;#cb3-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;  from ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Natural&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; (s, &lt;span class=&quot;dt&quot;&gt;Natural&lt;/span&gt;)&lt;/span&gt;
&lt;span id=&quot;cb3-7&quot;&gt;&lt;a href=&quot;#cb3-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  from n &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-8&quot;&gt;&lt;a href=&quot;#cb3-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;kw&quot;&gt;let&lt;/span&gt; s &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; classify n&lt;/span&gt;
&lt;span id=&quot;cb3-9&quot;&gt;&lt;a href=&quot;#cb3-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;        n&amp;#39; &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; genericLength [ () &lt;span class=&quot;op&quot;&gt;|&lt;/span&gt; k &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; [b&lt;span class=&quot;op&quot;&gt;..&lt;/span&gt;n], classify k &lt;span class=&quot;op&quot;&gt;==&lt;/span&gt; s ]&lt;/span&gt;
&lt;span id=&quot;cb3-10&quot;&gt;&lt;a href=&quot;#cb3-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;kw&quot;&gt;in&lt;/span&gt; (s, n&amp;#39;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;For every function &lt;span class=&quot;math inline&quot;&gt;\(g_1\colon
\mathbb{Z}_{\geq \beta} \to \{0,\ldots,B-1\}\)&lt;/span&gt; (named
&lt;code&gt;classify&lt;/code&gt; in Haskell), we have a pair of encode/decode
functions, provided that each of the sets &lt;span
class=&quot;math inline&quot;&gt;\(A_s\)&lt;/span&gt; is infinite. In particular, we can
get the standard encode/decode functions (originally defined by
&lt;code&gt;std_iso&lt;/code&gt;) by setting &lt;code&gt;classify&lt;/code&gt; to&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb4&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb4-1&quot;&gt;&lt;a href=&quot;#cb4-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;classify_mod_base ::&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;forall&lt;/span&gt; s &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;Bounded&lt;/span&gt; s, &lt;span class=&quot;dt&quot;&gt;Enum&lt;/span&gt; s) &lt;span class=&quot;ot&quot;&gt;=&amp;gt;&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;Natural&lt;/span&gt;, &lt;span class=&quot;dt&quot;&gt;Natural&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; s)&lt;/span&gt;
&lt;span id=&quot;cb4-2&quot;&gt;&lt;a href=&quot;#cb4-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;classify_mod_base &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; (base &lt;span class=&quot;op&quot;&gt;@&lt;/span&gt;s, \n &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; n2s (n &lt;span class=&quot;ot&quot;&gt;`mod`&lt;/span&gt; base &lt;span class=&quot;op&quot;&gt;@&lt;/span&gt;s))&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;By varying &lt;span class=&quot;math inline&quot;&gt;\(g_1\)&lt;/span&gt; (and therefore
the sets &lt;span class=&quot;math inline&quot;&gt;\(A_s\)&lt;/span&gt;), we can control which
inputs get mapped to smaller integers.&lt;/p&gt;
&lt;p&gt;If &lt;span class=&quot;math inline&quot;&gt;\(A_s\)&lt;/span&gt; is more dense, &lt;span
class=&quot;math inline&quot;&gt;\(f(s,n)\)&lt;/span&gt;, defined as &lt;span
class=&quot;math inline&quot;&gt;\(n\)&lt;/span&gt;th smallest number in &lt;span
class=&quot;math inline&quot;&gt;\(A_s\)&lt;/span&gt;, will be smaller.&lt;/p&gt;
&lt;p&gt;If &lt;span class=&quot;math inline&quot;&gt;\(A_s\)&lt;/span&gt; is more sparse, &lt;span
class=&quot;math inline&quot;&gt;\(f(s,n)\)&lt;/span&gt; will be larger.&lt;/p&gt;
&lt;p&gt;The standard isomorphism makes the sets &lt;span
class=&quot;math display&quot;&gt;\[A_s = \{ s+n\cdot B \mid n\in \mathbb Z_{\geq 1}
\} \]&lt;/span&gt; equally dense for all values of &lt;span
class=&quot;math inline&quot;&gt;\(s\)&lt;/span&gt;. This makes sense when all &lt;span
class=&quot;math inline&quot;&gt;\(s\)&lt;/span&gt; are equally probable.&lt;/p&gt;
&lt;p&gt;But in general, we should make &lt;span
class=&quot;math inline&quot;&gt;\(A_s\)&lt;/span&gt; denser for those &lt;span
class=&quot;math inline&quot;&gt;\(s\)&lt;/span&gt; that are more frequent. Specifically,
we want&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;math display&quot;&gt;\[
\frac{|\{k\in A_s \mid k \leq x\}|}{x} \approx p_s.
\]&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Substituting &lt;span class=&quot;math inline&quot;&gt;\(x=f(s,n)\)&lt;/span&gt; then gives
&lt;span class=&quot;math inline&quot;&gt;\(\log_2 f(s,n) \approx \log_2 n + \log_2
(1/p_s)\)&lt;/span&gt;. This means that adding a symbol &lt;span
class=&quot;math inline&quot;&gt;\(s\)&lt;/span&gt; costs &lt;span
class=&quot;math inline&quot;&gt;\(\log_2 (1/p_s)\)&lt;/span&gt; bits, which is &lt;a
href=&quot;https://en.wikipedia.org/wiki/Entropy_encoding&quot;&gt;what we should
strive for&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Here’s a simple example of a suitable &lt;span
class=&quot;math inline&quot;&gt;\(g_1\)&lt;/span&gt;:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb5&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb5-1&quot;&gt;&lt;a href=&quot;#cb5-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;classify_prob ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Show&lt;/span&gt; s &lt;span class=&quot;ot&quot;&gt;=&amp;gt;&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;Bounded&lt;/span&gt; s, &lt;span class=&quot;dt&quot;&gt;Enum&lt;/span&gt; s) &lt;span class=&quot;ot&quot;&gt;=&amp;gt;&lt;/span&gt; [&lt;span class=&quot;dt&quot;&gt;Double&lt;/span&gt;] &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;Natural&lt;/span&gt;, &lt;span class=&quot;dt&quot;&gt;Natural&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; s)&lt;/span&gt;
&lt;span id=&quot;cb5-2&quot;&gt;&lt;a href=&quot;#cb5-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;classify_prob probs &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-3&quot;&gt;&lt;a href=&quot;#cb5-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;let&lt;/span&gt; beta &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;co&quot;&gt;-- arbitrary number &amp;gt; 1&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-4&quot;&gt;&lt;a href=&quot;#cb5-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      t &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; genericLength l&lt;/span&gt;
&lt;span id=&quot;cb5-5&quot;&gt;&lt;a href=&quot;#cb5-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      l &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;concatMap&lt;/span&gt; (\(s, t) &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;replicate&lt;/span&gt; t s)&lt;/span&gt;
&lt;span id=&quot;cb5-6&quot;&gt;&lt;a href=&quot;#cb5-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;        &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt; sortBy (comparing (&lt;span class=&quot;dt&quot;&gt;Down&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;snd&lt;/span&gt;))&lt;/span&gt;
&lt;span id=&quot;cb5-7&quot;&gt;&lt;a href=&quot;#cb5-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;        &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;zip&lt;/span&gt; [&lt;span class=&quot;fu&quot;&gt;minBound&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;..&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;maxBound&lt;/span&gt;]&lt;/span&gt;
&lt;span id=&quot;cb5-8&quot;&gt;&lt;a href=&quot;#cb5-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;        &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;map&lt;/span&gt; (&lt;span class=&quot;fu&quot;&gt;round&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt; (&lt;span class=&quot;op&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;minimum&lt;/span&gt; probs)) probs&lt;/span&gt;
&lt;span id=&quot;cb5-9&quot;&gt;&lt;a href=&quot;#cb5-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      g1 n &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; l &lt;span class=&quot;ot&quot;&gt;`genericIndex`&lt;/span&gt; ((n&lt;span class=&quot;op&quot;&gt;-&lt;/span&gt;beta) &lt;span class=&quot;ot&quot;&gt;`mod`&lt;/span&gt; t)&lt;/span&gt;
&lt;span id=&quot;cb5-10&quot;&gt;&lt;a href=&quot;#cb5-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;in&lt;/span&gt; (beta, g1)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This is a periodic function. It computes the number of times each
symbol &lt;span class=&quot;math inline&quot;&gt;\(s\)&lt;/span&gt; will appear within a
single period as &lt;span class=&quot;math inline&quot;&gt;\(k_s=\mathrm{round}(p_s/\min
\{p_s\})\)&lt;/span&gt;. The number &lt;span class=&quot;math inline&quot;&gt;\(p_s/\min
\{p_s\}\)&lt;/span&gt; is chosen for its following two properties:&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;it is proportional to the probability of the symbol, &lt;span
class=&quot;math inline&quot;&gt;\(p_s\)&lt;/span&gt;;&lt;/li&gt;
&lt;li&gt;it is &lt;span class=&quot;math inline&quot;&gt;\(\geq 1\)&lt;/span&gt;, so that even the
least likely symbol occurs among the values of the function.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The function then works by mapping the first &lt;span
class=&quot;math inline&quot;&gt;\(k_0\)&lt;/span&gt; numbers to symbol &lt;span
class=&quot;math inline&quot;&gt;\(0\)&lt;/span&gt;, the next &lt;span
class=&quot;math inline&quot;&gt;\(k_1\)&lt;/span&gt; numbers to symbol &lt;span
class=&quot;math inline&quot;&gt;\(1\)&lt;/span&gt;, and so on, until it maps &lt;span
class=&quot;math inline&quot;&gt;\(k_{B-1}\)&lt;/span&gt; numbers to symbol &lt;span
class=&quot;math inline&quot;&gt;\(B-1\)&lt;/span&gt; and repeats itself. The period of the
function is &lt;span class=&quot;math inline&quot;&gt;\(\sum_s k_s\approx 1/\min
\{p_s\}\)&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;classify_prob&lt;/code&gt; rearranges the symbols in the order of
decreasing probability, which gives further advantage to the more
probable symbols. This is probably the best strategy if we want to
allocate integers in blocks; a better way would be to interleave the
blocks in a fair or random way in order to keep the densities more
uniform.&lt;/p&gt;
&lt;p&gt;Another downside of this function is that its period may be too small
to distinguish between similar probabilities, such as 0.4 and 0.6. The
function used in rANS is better in this regard; it uses progressively
larger intervals, which provide progressively better approximations.&lt;/p&gt;
&lt;p&gt;But &lt;code&gt;classify_prob&lt;/code&gt; is enough to demonstate the idea.
Let’s encode a list of booleans where &lt;code&gt;True&lt;/code&gt; is expected 90%
of time.&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb6&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb6-1&quot;&gt;&lt;a href=&quot;#cb6-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;op&quot;&gt;&amp;gt;&lt;/span&gt; iso &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; ans_iso &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; classify_prob [&lt;span class=&quot;fl&quot;&gt;0.1&lt;/span&gt;,&lt;span class=&quot;fl&quot;&gt;0.9&lt;/span&gt;]&lt;/span&gt;
&lt;span id=&quot;cb6-2&quot;&gt;&lt;a href=&quot;#cb6-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;op&quot;&gt;&amp;gt;&lt;/span&gt; encode iso (&lt;span class=&quot;fu&quot;&gt;replicate&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;4&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;True&lt;/span&gt;)&lt;/span&gt;
&lt;span id=&quot;cb6-3&quot;&gt;&lt;a href=&quot;#cb6-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;dv&quot;&gt;5&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-4&quot;&gt;&lt;a href=&quot;#cb6-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;op&quot;&gt;&amp;gt;&lt;/span&gt; encode iso (&lt;span class=&quot;fu&quot;&gt;replicate&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;4&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;False&lt;/span&gt;)&lt;/span&gt;
&lt;span id=&quot;cb6-5&quot;&gt;&lt;a href=&quot;#cb6-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;dv&quot;&gt;11111&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Four &lt;code&gt;True&lt;/code&gt;s compress much better than four
&lt;code&gt;False&lt;/code&gt;s. Let’s also compare the number of bits in 11111 with
the number of bits that the information theory predicts are needed to
encode four events with probability 0.1:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb7&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb7-1&quot;&gt;&lt;a href=&quot;#cb7-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;op&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;logBase&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;11111&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb7-2&quot;&gt;&lt;a href=&quot;#cb7-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;fl&quot;&gt;13.439701045971955&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb7-3&quot;&gt;&lt;a href=&quot;#cb7-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;op&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;4&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;logBase&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;2&lt;/span&gt; (&lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;fl&quot;&gt;0.1&lt;/span&gt;)&lt;/span&gt;
&lt;span id=&quot;cb7-4&quot;&gt;&lt;a href=&quot;#cb7-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;fl&quot;&gt;13.28771237954945&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Not bad.&lt;/p&gt;
&lt;p&gt;The implementation of ANS in this article is terribly inefficient,
especially its decoding part, mostly because the isomorphism uses brute
force search instead of computation. The intention is to elucidate what
the encoding scheme looks like and where it comes from. An efficient
implementation of ANS and its different variants is an interesting topic
in itself, but I’ll leave it for another day.&lt;/p&gt;
&lt;p&gt;The full code (including tests) is available &lt;a
href=&quot;/files/2017-08-20-understanding-ans.hs&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Thanks to /u/sgraf812 for &lt;a
href=&quot;https://www.reddit.com/r/haskell/comments/6v4tg1/understanding_asymmetric_numeral_systems_with/dlyjc1u/&quot;&gt;pointing
out&lt;/a&gt; a mistake in a previous version of
&lt;code&gt;classify_prob&lt;/code&gt;.&lt;/p&gt;
</description>
                        <pubDate>Sun, 20 Aug 2017 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2017-08-20-understanding-ans</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2017-08-20-understanding-ans.html</guid>
                </item>
        
                <item>
                        <title>Call an R function from C</title>
                        <description>&lt;p&gt;This article explains how to call an R function from a C
extension.&lt;/p&gt;
&lt;p&gt;The “Writing R Extensions” guide gives &lt;a
href=&quot;https://cran.r-project.org/doc/manuals/R-exts.html#index-Evaluating-R-expressions-from-C&quot;&gt;such
an example&lt;/a&gt;, but their approach — composing an expression and then
evaluating it — strikes me as unnecessarily complicated and
roundabout.&lt;/p&gt;
&lt;p&gt;Instead, you can use the &lt;code&gt;R_forceAndCall&lt;/code&gt; function:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb1&quot;&gt;&lt;pre class=&quot;sourceCode c&quot;&gt;&lt;code class=&quot;sourceCode c&quot;&gt;&lt;span id=&quot;cb1-1&quot;&gt;&lt;a href=&quot;#cb1-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;SEXP R_forceAndCall&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;SEXP e&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;int&lt;/span&gt; n&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; SEXP rho&lt;span class=&quot;op&quot;&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This C function is not documented or part of the &lt;a
href=&quot;https://cran.r-project.org/doc/manuals/R-exts.html#The-R-API&quot;&gt;official
API&lt;/a&gt;, so use it on your own risk. We can get some idea about what it
does by reading the &lt;a
href=&quot;https://stat.ethz.ch/R-manual/R-devel/library/base/html/forceAndCall.html&quot;&gt;documentation&lt;/a&gt;
for the corresponding R function, &lt;code&gt;forceAndCall&lt;/code&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Call a function with a specified number of leading arguments forced
before the call if the function is a closure.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;So the arguments to &lt;code&gt;R_forceAndCall&lt;/code&gt; are:&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;&lt;code&gt;int n&lt;/code&gt; — the number of arguments to force.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;SEXP e&lt;/code&gt; — a call object — a &lt;code&gt;LANGSXP&lt;/code&gt; linked
list whose head is the function object and whose tail is function
arguments. You construct such lists with the &lt;code&gt;LCONS&lt;/code&gt; macro,
end them with &lt;code&gt;R_NilValue&lt;/code&gt; (which corresponds to R’s
&lt;code&gt;NULL&lt;/code&gt;), and assign argument names using the
&lt;code&gt;SET_TAG&lt;/code&gt; macro (if needed).&lt;/li&gt;
&lt;li&gt;&lt;code&gt;SEXP rho&lt;/code&gt; — the environment in which the evaluation will
happen.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;This suggests the following implementation:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb2&quot;&gt;&lt;pre class=&quot;sourceCode c&quot;&gt;&lt;code class=&quot;sourceCode c&quot;&gt;&lt;span id=&quot;cb2-1&quot;&gt;&lt;a href=&quot;#cb2-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;pp&quot;&gt;#include &lt;/span&gt;&lt;span class=&quot;im&quot;&gt;&amp;lt;Rinternals.h&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-2&quot;&gt;&lt;a href=&quot;#cb2-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-3&quot;&gt;&lt;a href=&quot;#cb2-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;SEXP R_apply_fun&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;SEXP f&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; SEXP x&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; SEXP rho&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-4&quot;&gt;&lt;a href=&quot;#cb2-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  SEXP call &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; PROTECT&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;LCONS&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;f&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; LCONS&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;x&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; R_NilValue&lt;span class=&quot;op&quot;&gt;)));&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-5&quot;&gt;&lt;a href=&quot;#cb2-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  SEXP val &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; R_forceAndCall&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;call&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; rho&lt;span class=&quot;op&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-6&quot;&gt;&lt;a href=&quot;#cb2-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  UNPROTECT&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-7&quot;&gt;&lt;a href=&quot;#cb2-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;cf&quot;&gt;return&lt;/span&gt; val&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-8&quot;&gt;&lt;a href=&quot;#cb2-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The code relies on the following comment found in
&lt;code&gt;do_lapply&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;/* Notice that it is OK to have one arg to LCONS do memory
   allocation and not PROTECT the result (LCONS does memory
   protection of its args internally), but not both of them,
   since the computation of one may destroy the other */&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The calling environment, &lt;code&gt;rho&lt;/code&gt;, needs to be passed in from
the R land. Even though R’s own functions can access the current
environment through &lt;code&gt;R_GlobalContext-&amp;gt;sysparent&lt;/code&gt; (see
&lt;code&gt;do_envir&lt;/code&gt;), neither &lt;code&gt;R_GlobalContext&lt;/code&gt; nor
&lt;code&gt;do_envir&lt;/code&gt; is part of the public API (i.e. they are not
declared in installed headers).&lt;/p&gt;
&lt;p&gt;So the R wrapper for &lt;code&gt;R_apply_fun&lt;/code&gt; should be something
like this:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb4&quot;&gt;&lt;pre class=&quot;sourceCode r&quot;&gt;&lt;code class=&quot;sourceCode r&quot;&gt;&lt;span id=&quot;cb4-1&quot;&gt;&lt;a href=&quot;#cb4-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;apply_fun &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;cf&quot;&gt;function&lt;/span&gt;(f, x) &lt;span class=&quot;fu&quot;&gt;.Call&lt;/span&gt;(R_apply_fun, f, x, &lt;span class=&quot;fu&quot;&gt;environment&lt;/span&gt;())&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The full example can be downloaded as a git repo:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;git clone https://ro-che.info/files/2017-08-18-call-r-function-from-c.git&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To test it, install the &lt;code&gt;devtools&lt;/code&gt; package, go to the
cloned repo, launch R, and run:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb6&quot;&gt;&lt;pre class=&quot;sourceCode r&quot;&gt;&lt;code class=&quot;sourceCode r&quot;&gt;&lt;span id=&quot;cb6-1&quot;&gt;&lt;a href=&quot;#cb6-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;devtools&lt;span class=&quot;sc&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;load_all&lt;/span&gt;()&lt;/span&gt;
&lt;span id=&quot;cb6-2&quot;&gt;&lt;a href=&quot;#cb6-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;fu&quot;&gt;apply_fun&lt;/span&gt;(&lt;span class=&quot;cf&quot;&gt;function&lt;/span&gt;(x) x&lt;span class=&quot;sc&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;, &lt;span class=&quot;dv&quot;&gt;3&lt;/span&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
</description>
                        <pubDate>Fri, 18 Aug 2017 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2017-08-18-call-r-function-from-c</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2017-08-18-call-r-function-from-c.html</guid>
                </item>
        
                <item>
                        <title>6 ways to manage allocated memory in Haskell</title>
                        <description>&lt;p&gt;Let’s say we have a foreign function that takes a C data structure.
Our task is to allocate the structure in memory, fill in the fields,
call the function, and deallocate the memory.&lt;/p&gt;
&lt;p&gt;The data structure is not flat but contains pointers to other data
structures that also need to be allocated. An example of such a data
structure is a linked list:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb1&quot;&gt;&lt;pre class=&quot;sourceCode c&quot;&gt;&lt;code class=&quot;sourceCode c&quot;&gt;&lt;span id=&quot;cb1-1&quot;&gt;&lt;a href=&quot;#cb1-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;typedef&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;struct&lt;/span&gt; list &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-2&quot;&gt;&lt;a href=&quot;#cb1-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;dt&quot;&gt;int&lt;/span&gt; car&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-3&quot;&gt;&lt;a href=&quot;#cb1-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;struct&lt;/span&gt; list &lt;span class=&quot;op&quot;&gt;*&lt;/span&gt;cdr&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-4&quot;&gt;&lt;a href=&quot;#cb1-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;op&quot;&gt;}&lt;/span&gt; list&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;And an example of a C function is one that computes the sum of all
elements in the list:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb2&quot;&gt;&lt;pre class=&quot;sourceCode c&quot;&gt;&lt;code class=&quot;sourceCode c&quot;&gt;&lt;span id=&quot;cb2-1&quot;&gt;&lt;a href=&quot;#cb2-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;dt&quot;&gt;int&lt;/span&gt; sum&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;list &lt;span class=&quot;op&quot;&gt;*&lt;/span&gt;l&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-2&quot;&gt;&lt;a href=&quot;#cb2-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;dt&quot;&gt;int&lt;/span&gt; s &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-3&quot;&gt;&lt;a href=&quot;#cb2-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;cf&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;l&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-4&quot;&gt;&lt;a href=&quot;#cb2-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    s &lt;span class=&quot;op&quot;&gt;+=&lt;/span&gt; l&lt;span class=&quot;op&quot;&gt;-&amp;gt;&lt;/span&gt;car&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-5&quot;&gt;&lt;a href=&quot;#cb2-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    l &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; l&lt;span class=&quot;op&quot;&gt;-&amp;gt;&lt;/span&gt;cdr&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-6&quot;&gt;&lt;a href=&quot;#cb2-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-7&quot;&gt;&lt;a href=&quot;#cb2-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;cf&quot;&gt;return&lt;/span&gt; s&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-8&quot;&gt;&lt;a href=&quot;#cb2-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;In this article, I will explore different ways to track all the
allocated pointers and free them reliably.&lt;/p&gt;
&lt;p&gt;The complete code can be downloaded as a git repo:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;git clone https://ro-che.info/files/2017-08-06-manage-allocated-memory-haskell.git&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The modules below use the &lt;a
href=&quot;https://downloads.haskell.org/~ghc/8.0.2/docs/html/users_guide/utils.html#writing-haskell-interfaces-to-c-code-hsc2hs&quot;&gt;hsc2hs&lt;/a&gt;
preprocessor; it replaces things like &lt;code&gt;#{peek ...}&lt;/code&gt;,
&lt;code&gt;#{poke ...}&lt;/code&gt;, and &lt;code&gt;#{size ...}&lt;/code&gt; with Haskell
code.&lt;/p&gt;
&lt;h2 id=&quot;way-1-traverse-the-structure&quot;&gt;Way 1: traverse the structure&lt;/h2&gt;
&lt;p&gt;Since all pointers are stored somewhere in the data structure, we
could traverse it to recover and free those pointers.&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb4&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb4-1&quot;&gt;&lt;a href=&quot;#cb4-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;mkList ::&lt;/span&gt; [&lt;span class=&quot;dt&quot;&gt;Int&lt;/span&gt;] &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;IO&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;Ptr&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;List&lt;/span&gt;)&lt;/span&gt;
&lt;span id=&quot;cb4-2&quot;&gt;&lt;a href=&quot;#cb4-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;mkList l &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-3&quot;&gt;&lt;a href=&quot;#cb4-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;case&lt;/span&gt; l &lt;span class=&quot;kw&quot;&gt;of&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-4&quot;&gt;&lt;a href=&quot;#cb4-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    [] &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;return&lt;/span&gt; nullPtr&lt;/span&gt;
&lt;span id=&quot;cb4-5&quot;&gt;&lt;a href=&quot;#cb4-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    x&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt;xs &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-6&quot;&gt;&lt;a href=&quot;#cb4-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      struct &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; mallocBytes &lt;span class=&quot;op&quot;&gt;#&lt;/span&gt;{size list}&lt;/span&gt;
&lt;span id=&quot;cb4-7&quot;&gt;&lt;a href=&quot;#cb4-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;op&quot;&gt;#&lt;/span&gt;{poke list, car} struct x&lt;/span&gt;
&lt;span id=&quot;cb4-8&quot;&gt;&lt;a href=&quot;#cb4-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      xs_c &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; mkList xs&lt;/span&gt;
&lt;span id=&quot;cb4-9&quot;&gt;&lt;a href=&quot;#cb4-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;op&quot;&gt;#&lt;/span&gt;{poke list, cdr} struct xs_c&lt;/span&gt;
&lt;span id=&quot;cb4-10&quot;&gt;&lt;a href=&quot;#cb4-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;fu&quot;&gt;return&lt;/span&gt; struct&lt;/span&gt;
&lt;span id=&quot;cb4-11&quot;&gt;&lt;a href=&quot;#cb4-11&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-12&quot;&gt;&lt;a href=&quot;#cb4-12&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;freeList ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Ptr&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;List&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;IO&lt;/span&gt; ()&lt;/span&gt;
&lt;span id=&quot;cb4-13&quot;&gt;&lt;a href=&quot;#cb4-13&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;freeList l&lt;/span&gt;
&lt;span id=&quot;cb4-14&quot;&gt;&lt;a href=&quot;#cb4-14&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;op&quot;&gt;|&lt;/span&gt; l &lt;span class=&quot;op&quot;&gt;==&lt;/span&gt; nullPtr &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;return&lt;/span&gt; ()&lt;/span&gt;
&lt;span id=&quot;cb4-15&quot;&gt;&lt;a href=&quot;#cb4-15&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;op&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;otherwise&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-16&quot;&gt;&lt;a href=&quot;#cb4-16&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      cdr &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;#&lt;/span&gt;{peek list, cdr} l&lt;/span&gt;
&lt;span id=&quot;cb4-17&quot;&gt;&lt;a href=&quot;#cb4-17&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      free l&lt;/span&gt;
&lt;span id=&quot;cb4-18&quot;&gt;&lt;a href=&quot;#cb4-18&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      freeList cdr&lt;/span&gt;
&lt;span id=&quot;cb4-19&quot;&gt;&lt;a href=&quot;#cb4-19&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-20&quot;&gt;&lt;a href=&quot;#cb4-20&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;way1 ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Int&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;IO&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Int&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-21&quot;&gt;&lt;a href=&quot;#cb4-21&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;way1 n &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; bracket (mkList [&lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;..&lt;/span&gt;n]) freeList csum&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This is how we’d probably do it in C, but in Haskell it has several
disadvantages compared to the other options we have:&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;The code to traverse the structure has to be written manually and is
prone to errors.&lt;/li&gt;
&lt;li&gt;Having to do the extra work of traversing the structure makes it
slower than some of the alternatives.&lt;/li&gt;
&lt;li&gt;It is not exception-safe; if something happens inside
&lt;code&gt;mkList&lt;/code&gt;, the already allocated pointers will be lost. Note
that this code is async-exception-safe (&lt;code&gt;bracket&lt;/code&gt; masks async
exceptions for &lt;code&gt;mkList&lt;/code&gt;), so the only exceptions we need to
worry about must come from &lt;code&gt;mkList&lt;/code&gt; or &lt;code&gt;freeList&lt;/code&gt;
(e.g. from &lt;code&gt;mallocBytes&lt;/code&gt;).&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;way-2-allocabytes-and-contt&quot;&gt;Way 2: allocaBytes and ContT&lt;/h2&gt;
&lt;p&gt;The &lt;code&gt;Foreign.Marshal.Alloc&lt;/code&gt; module provides the
&lt;code&gt;bracket&lt;/code&gt;-style &lt;code&gt;allocaBytes&lt;/code&gt; function, which
allocates the memory and then automatically releases it.&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb5&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb5-1&quot;&gt;&lt;a href=&quot;#cb5-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;co&quot;&gt;-- |@&amp;#39;allocaBytes&amp;#39; n f@ executes the computation @f@, passing as argument&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-2&quot;&gt;&lt;a href=&quot;#cb5-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;co&quot;&gt;-- a pointer to a temporarily allocated block of memory of @n@ bytes.&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-3&quot;&gt;&lt;a href=&quot;#cb5-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;co&quot;&gt;-- The block of memory is sufficiently aligned for any of the basic&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-4&quot;&gt;&lt;a href=&quot;#cb5-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;co&quot;&gt;-- foreign types that fits into a memory block of the allocated size.&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-5&quot;&gt;&lt;a href=&quot;#cb5-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;co&quot;&gt;--&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-6&quot;&gt;&lt;a href=&quot;#cb5-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;co&quot;&gt;-- The memory is freed when @f@ terminates (either normally or via an&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-7&quot;&gt;&lt;a href=&quot;#cb5-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;co&quot;&gt;-- exception), so the pointer passed to @f@ must /not/ be used after this.&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-8&quot;&gt;&lt;a href=&quot;#cb5-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;allocaBytes ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Int&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;Ptr&lt;/span&gt; a &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;IO&lt;/span&gt; b) &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;IO&lt;/span&gt; b&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;It works great if we need to allocate a small fixed number of
structures:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb6&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb6-1&quot;&gt;&lt;a href=&quot;#cb6-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;allocaBytes size1 &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; \ptr1 &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-2&quot;&gt;&lt;a href=&quot;#cb6-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  allocaBytes size2 &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; \ptr2 &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-3&quot;&gt;&lt;a href=&quot;#cb6-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;co&quot;&gt;-- do something with ptr1 and ptr2&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;But what if the number of allocations is large or even unknown, as in
our case?&lt;/p&gt;
&lt;p&gt;For that, we have the continuation monad!&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb7&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb7-1&quot;&gt;&lt;a href=&quot;#cb7-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;mallocBytesC ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Int&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;ContT&lt;/span&gt; r &lt;span class=&quot;dt&quot;&gt;IO&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;Ptr&lt;/span&gt; a)&lt;/span&gt;
&lt;span id=&quot;cb7-2&quot;&gt;&lt;a href=&quot;#cb7-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;mallocBytesC n &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;ContT&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; \k &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; allocaBytes n k&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;mallocBytesC&lt;/code&gt; is a monadic function that returns a
pointer to the allocated memory, so it is as convenient and flexible as
the simple &lt;code&gt;mallocBytes&lt;/code&gt; used in Way 1. But, unlike
&lt;code&gt;mallocBytes&lt;/code&gt;, all allocated memory will be safely and
automatically released at the point where we run the &lt;code&gt;ContT&lt;/code&gt;
layer.&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb8&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb8-1&quot;&gt;&lt;a href=&quot;#cb8-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;mkList ::&lt;/span&gt; [&lt;span class=&quot;dt&quot;&gt;Int&lt;/span&gt;] &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;ContT&lt;/span&gt; r &lt;span class=&quot;dt&quot;&gt;IO&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;Ptr&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;List&lt;/span&gt;)&lt;/span&gt;
&lt;span id=&quot;cb8-2&quot;&gt;&lt;a href=&quot;#cb8-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;mkList l &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb8-3&quot;&gt;&lt;a href=&quot;#cb8-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;case&lt;/span&gt; l &lt;span class=&quot;kw&quot;&gt;of&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb8-4&quot;&gt;&lt;a href=&quot;#cb8-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    [] &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;return&lt;/span&gt; nullPtr&lt;/span&gt;
&lt;span id=&quot;cb8-5&quot;&gt;&lt;a href=&quot;#cb8-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    x&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt;xs &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb8-6&quot;&gt;&lt;a href=&quot;#cb8-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      struct &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; mallocBytesC &lt;span class=&quot;op&quot;&gt;#&lt;/span&gt;{size list}&lt;/span&gt;
&lt;span id=&quot;cb8-7&quot;&gt;&lt;a href=&quot;#cb8-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      liftIO &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;#&lt;/span&gt;{poke list, car} struct x&lt;/span&gt;
&lt;span id=&quot;cb8-8&quot;&gt;&lt;a href=&quot;#cb8-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      xs_c &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; mkList xs&lt;/span&gt;
&lt;span id=&quot;cb8-9&quot;&gt;&lt;a href=&quot;#cb8-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      liftIO &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;#&lt;/span&gt;{poke list, cdr} struct xs_c&lt;/span&gt;
&lt;span id=&quot;cb8-10&quot;&gt;&lt;a href=&quot;#cb8-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;fu&quot;&gt;return&lt;/span&gt; struct&lt;/span&gt;
&lt;span id=&quot;cb8-11&quot;&gt;&lt;a href=&quot;#cb8-11&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb8-12&quot;&gt;&lt;a href=&quot;#cb8-12&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;way2 ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Int&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;IO&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Int&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb8-13&quot;&gt;&lt;a href=&quot;#cb8-13&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;way2 n &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; runContT (liftIO &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt; csum &lt;span class=&quot;op&quot;&gt;=&amp;lt;&amp;lt;&lt;/span&gt; mkList [&lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;..&lt;/span&gt;n]) &lt;span class=&quot;fu&quot;&gt;return&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This is my favorite way: it is simple, safe, fast, and elegant.&lt;/p&gt;
&lt;h2 id=&quot;way-3-resourcet&quot;&gt;Way 3: ResourceT&lt;/h2&gt;
&lt;p&gt;If we replace &lt;code&gt;ContT r&lt;/code&gt; with &lt;code&gt;ResourceT&lt;/code&gt;, we
get a similar function with essentially the same semantics: the memory
released when the &lt;code&gt;ResourceT&lt;/code&gt; layer is run.&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb9&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb9-1&quot;&gt;&lt;a href=&quot;#cb9-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;mallocBytesR ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Int&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;ResourceT&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;IO&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;Ptr&lt;/span&gt; a)&lt;/span&gt;
&lt;span id=&quot;cb9-2&quot;&gt;&lt;a href=&quot;#cb9-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;mallocBytesR n &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;snd&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;&amp;lt;$&amp;gt;&lt;/span&gt; allocate (mallocBytes n) free&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The rest of the code barely changes:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb10&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb10-1&quot;&gt;&lt;a href=&quot;#cb10-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;mkList ::&lt;/span&gt; [&lt;span class=&quot;dt&quot;&gt;Int&lt;/span&gt;] &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;ResourceT&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;IO&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;Ptr&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;List&lt;/span&gt;)&lt;/span&gt;
&lt;span id=&quot;cb10-2&quot;&gt;&lt;a href=&quot;#cb10-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;mkList l &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb10-3&quot;&gt;&lt;a href=&quot;#cb10-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;case&lt;/span&gt; l &lt;span class=&quot;kw&quot;&gt;of&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb10-4&quot;&gt;&lt;a href=&quot;#cb10-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    [] &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;return&lt;/span&gt; nullPtr&lt;/span&gt;
&lt;span id=&quot;cb10-5&quot;&gt;&lt;a href=&quot;#cb10-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    x&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt;xs &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb10-6&quot;&gt;&lt;a href=&quot;#cb10-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      struct &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; mallocBytesR &lt;span class=&quot;op&quot;&gt;#&lt;/span&gt;{size list}&lt;/span&gt;
&lt;span id=&quot;cb10-7&quot;&gt;&lt;a href=&quot;#cb10-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      liftIO &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;#&lt;/span&gt;{poke list, car} struct x&lt;/span&gt;
&lt;span id=&quot;cb10-8&quot;&gt;&lt;a href=&quot;#cb10-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      xs_c &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; mkList xs&lt;/span&gt;
&lt;span id=&quot;cb10-9&quot;&gt;&lt;a href=&quot;#cb10-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      liftIO &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;#&lt;/span&gt;{poke list, cdr} struct xs_c&lt;/span&gt;
&lt;span id=&quot;cb10-10&quot;&gt;&lt;a href=&quot;#cb10-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;fu&quot;&gt;return&lt;/span&gt; struct&lt;/span&gt;
&lt;span id=&quot;cb10-11&quot;&gt;&lt;a href=&quot;#cb10-11&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb10-12&quot;&gt;&lt;a href=&quot;#cb10-12&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;way3 ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Int&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;IO&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Int&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb10-13&quot;&gt;&lt;a href=&quot;#cb10-13&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;way3 n &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; runResourceT (liftIO &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt; csum &lt;span class=&quot;op&quot;&gt;=&amp;lt;&amp;lt;&lt;/span&gt; mkList [&lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;..&lt;/span&gt;n])&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;However, as we shall see, this version is an order of magnitude
slower than the &lt;code&gt;ContT&lt;/code&gt; version.&lt;/p&gt;
&lt;h2 id=&quot;way-4-single-block-allocation-via-mallocbytes&quot;&gt;Way 4:
single-block allocation via mallocBytes&lt;/h2&gt;
&lt;p&gt;Even though our structure contains lots of pointers, we don’t have to
allocate each one of them separately. Instead, we could allocate a
single chunk of memory and calculate the pointers ourselves.&lt;/p&gt;
&lt;p&gt;This method may be more involved for complex data structures, but it
is the fastest one, because we only need to keep track of and deallocate
a single pointer.&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb11&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb11-1&quot;&gt;&lt;a href=&quot;#cb11-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;writeList ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Ptr&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;List&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; [&lt;span class=&quot;dt&quot;&gt;Int&lt;/span&gt;] &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;IO&lt;/span&gt; ()&lt;/span&gt;
&lt;span id=&quot;cb11-2&quot;&gt;&lt;a href=&quot;#cb11-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;writeList ptr l &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb11-3&quot;&gt;&lt;a href=&quot;#cb11-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;case&lt;/span&gt; l &lt;span class=&quot;kw&quot;&gt;of&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb11-4&quot;&gt;&lt;a href=&quot;#cb11-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    [] &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;error&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;quot;writeList: empty list&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb11-5&quot;&gt;&lt;a href=&quot;#cb11-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    [x] &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb11-6&quot;&gt;&lt;a href=&quot;#cb11-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;op&quot;&gt;#&lt;/span&gt;{poke list, car} ptr x&lt;/span&gt;
&lt;span id=&quot;cb11-7&quot;&gt;&lt;a href=&quot;#cb11-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;op&quot;&gt;#&lt;/span&gt;{poke list, cdr} ptr nullPtr&lt;/span&gt;
&lt;span id=&quot;cb11-8&quot;&gt;&lt;a href=&quot;#cb11-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    x&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt;xs &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb11-9&quot;&gt;&lt;a href=&quot;#cb11-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;op&quot;&gt;#&lt;/span&gt;{poke list, car} ptr x&lt;/span&gt;
&lt;span id=&quot;cb11-10&quot;&gt;&lt;a href=&quot;#cb11-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;kw&quot;&gt;let&lt;/span&gt; ptr&amp;#39; &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; plusPtr ptr &lt;span class=&quot;op&quot;&gt;#&lt;/span&gt;{size list}&lt;/span&gt;
&lt;span id=&quot;cb11-11&quot;&gt;&lt;a href=&quot;#cb11-11&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;op&quot;&gt;#&lt;/span&gt;{poke list, cdr} ptr ptr&amp;#39;&lt;/span&gt;
&lt;span id=&quot;cb11-12&quot;&gt;&lt;a href=&quot;#cb11-12&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      writeList ptr&amp;#39; xs&lt;/span&gt;
&lt;span id=&quot;cb11-13&quot;&gt;&lt;a href=&quot;#cb11-13&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb11-14&quot;&gt;&lt;a href=&quot;#cb11-14&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;mkList ::&lt;/span&gt; [&lt;span class=&quot;dt&quot;&gt;Int&lt;/span&gt;] &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;IO&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;Ptr&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;List&lt;/span&gt;)&lt;/span&gt;
&lt;span id=&quot;cb11-15&quot;&gt;&lt;a href=&quot;#cb11-15&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;mkList l&lt;/span&gt;
&lt;span id=&quot;cb11-16&quot;&gt;&lt;a href=&quot;#cb11-16&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;op&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;null&lt;/span&gt; l &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;return&lt;/span&gt; nullPtr&lt;/span&gt;
&lt;span id=&quot;cb11-17&quot;&gt;&lt;a href=&quot;#cb11-17&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;op&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;otherwise&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb11-18&quot;&gt;&lt;a href=&quot;#cb11-18&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      ptr &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; mallocBytes (&lt;span class=&quot;fu&quot;&gt;length&lt;/span&gt; l &lt;span class=&quot;op&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;#&lt;/span&gt;{size list})&lt;/span&gt;
&lt;span id=&quot;cb11-19&quot;&gt;&lt;a href=&quot;#cb11-19&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      writeList ptr l&lt;/span&gt;
&lt;span id=&quot;cb11-20&quot;&gt;&lt;a href=&quot;#cb11-20&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;fu&quot;&gt;return&lt;/span&gt; ptr&lt;/span&gt;
&lt;span id=&quot;cb11-21&quot;&gt;&lt;a href=&quot;#cb11-21&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb11-22&quot;&gt;&lt;a href=&quot;#cb11-22&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;way4 ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Int&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;IO&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Int&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb11-23&quot;&gt;&lt;a href=&quot;#cb11-23&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;way4 n &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; bracket (mkList [&lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;..&lt;/span&gt;n]) free csum&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;way-5-single-block-allocation-via-allocabytes-contt&quot;&gt;Way 5:
single-block allocation via allocaBytes + ContT&lt;/h2&gt;
&lt;p&gt;This is the same as Way 4, except using &lt;code&gt;allocaBytes&lt;/code&gt;
instead of &lt;code&gt;mallocBytes&lt;/code&gt;. The two functions allocate the
memory differently, so I thought I’d add this version to the
benchmark.&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb12&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb12-1&quot;&gt;&lt;a href=&quot;#cb12-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;mkList ::&lt;/span&gt; [&lt;span class=&quot;dt&quot;&gt;Int&lt;/span&gt;] &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;ContT&lt;/span&gt; r &lt;span class=&quot;dt&quot;&gt;IO&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;Ptr&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;List&lt;/span&gt;)&lt;/span&gt;
&lt;span id=&quot;cb12-2&quot;&gt;&lt;a href=&quot;#cb12-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;mkList l&lt;/span&gt;
&lt;span id=&quot;cb12-3&quot;&gt;&lt;a href=&quot;#cb12-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;op&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;null&lt;/span&gt; l &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;return&lt;/span&gt; nullPtr&lt;/span&gt;
&lt;span id=&quot;cb12-4&quot;&gt;&lt;a href=&quot;#cb12-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;op&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;otherwise&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb12-5&quot;&gt;&lt;a href=&quot;#cb12-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      ptr &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; mallocBytesC (&lt;span class=&quot;fu&quot;&gt;length&lt;/span&gt; l &lt;span class=&quot;op&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;#&lt;/span&gt;{size list})&lt;/span&gt;
&lt;span id=&quot;cb12-6&quot;&gt;&lt;a href=&quot;#cb12-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      liftIO &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; writeList ptr l&lt;/span&gt;
&lt;span id=&quot;cb12-7&quot;&gt;&lt;a href=&quot;#cb12-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;fu&quot;&gt;return&lt;/span&gt; ptr&lt;/span&gt;
&lt;span id=&quot;cb12-8&quot;&gt;&lt;a href=&quot;#cb12-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb12-9&quot;&gt;&lt;a href=&quot;#cb12-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;way5 ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Int&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;IO&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Int&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb12-10&quot;&gt;&lt;a href=&quot;#cb12-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;way5 n &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; runContT (liftIO &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt; csum &lt;span class=&quot;op&quot;&gt;=&amp;lt;&amp;lt;&lt;/span&gt; mkList [&lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;..&lt;/span&gt;n]) &lt;span class=&quot;fu&quot;&gt;return&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;way-6-managed&quot;&gt;Way 6: managed&lt;/h2&gt;
&lt;p&gt;This is the same as Way 2, but using the &lt;a
href=&quot;https://hackage.haskell.org/package/managed&quot;&gt;managed&lt;/a&gt; library
by Gabriel Gonzalez. (Thanks to reddit user /u/andriusst for bringing it
up.)&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb13&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb13-1&quot;&gt;&lt;a href=&quot;#cb13-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;mallocBytesC ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Int&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Managed&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;Ptr&lt;/span&gt; a)&lt;/span&gt;
&lt;span id=&quot;cb13-2&quot;&gt;&lt;a href=&quot;#cb13-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;mallocBytesC n &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; managed &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; \k &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; allocaBytes n k&lt;/span&gt;
&lt;span id=&quot;cb13-3&quot;&gt;&lt;a href=&quot;#cb13-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb13-4&quot;&gt;&lt;a href=&quot;#cb13-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;mkList ::&lt;/span&gt; [&lt;span class=&quot;dt&quot;&gt;Int&lt;/span&gt;] &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Managed&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;Ptr&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;List&lt;/span&gt;)&lt;/span&gt;
&lt;span id=&quot;cb13-5&quot;&gt;&lt;a href=&quot;#cb13-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;mkList l &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb13-6&quot;&gt;&lt;a href=&quot;#cb13-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;case&lt;/span&gt; l &lt;span class=&quot;kw&quot;&gt;of&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb13-7&quot;&gt;&lt;a href=&quot;#cb13-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    [] &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;return&lt;/span&gt; nullPtr&lt;/span&gt;
&lt;span id=&quot;cb13-8&quot;&gt;&lt;a href=&quot;#cb13-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    x&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt;xs &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb13-9&quot;&gt;&lt;a href=&quot;#cb13-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      struct &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; mallocBytesC &lt;span class=&quot;op&quot;&gt;#&lt;/span&gt;{size list}&lt;/span&gt;
&lt;span id=&quot;cb13-10&quot;&gt;&lt;a href=&quot;#cb13-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      liftIO &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;#&lt;/span&gt;{poke list, car} struct x&lt;/span&gt;
&lt;span id=&quot;cb13-11&quot;&gt;&lt;a href=&quot;#cb13-11&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      xs_c &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; mkList xs&lt;/span&gt;
&lt;span id=&quot;cb13-12&quot;&gt;&lt;a href=&quot;#cb13-12&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      liftIO &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;#&lt;/span&gt;{poke list, cdr} struct xs_c&lt;/span&gt;
&lt;span id=&quot;cb13-13&quot;&gt;&lt;a href=&quot;#cb13-13&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;fu&quot;&gt;return&lt;/span&gt; struct&lt;/span&gt;
&lt;span id=&quot;cb13-14&quot;&gt;&lt;a href=&quot;#cb13-14&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb13-15&quot;&gt;&lt;a href=&quot;#cb13-15&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;way6 ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Int&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;IO&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Int&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb13-16&quot;&gt;&lt;a href=&quot;#cb13-16&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;way6 n &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; with (liftIO &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt; csum &lt;span class=&quot;op&quot;&gt;=&amp;lt;&amp;lt;&lt;/span&gt; mkList [&lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;..&lt;/span&gt;n]) &lt;span class=&quot;fu&quot;&gt;return&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;Managed&lt;/code&gt; is just a newtype wrapper around the polymorphic
continuation monad (a.k.a. the Codensity monad) applied to
&lt;code&gt;IO&lt;/code&gt;. Because the underlying implementation is the same, the
run time performance is exactly that of Way 2, but you get to work with
simpler types: &lt;code&gt;Managed&lt;/code&gt; instead of
&lt;code&gt;ContT r IO&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&quot;is-sum-pure&quot;&gt;Is sum pure?&lt;/h2&gt;
&lt;p&gt;We expose the &lt;code&gt;sum&lt;/code&gt; function from C as an IO function
&lt;code&gt;csum&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb14&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb14-1&quot;&gt;&lt;a href=&quot;#cb14-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;foreign &lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; ccall &amp;quot;sum&amp;quot; csum :: &lt;span class=&quot;dt&quot;&gt;Ptr&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;List&lt;/span&gt; -&amp;gt; &lt;span class=&quot;dt&quot;&gt;IO&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Int&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The alternative is to expose it as a pure function:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb15&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb15-1&quot;&gt;&lt;a href=&quot;#cb15-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;foreign &lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; ccall &amp;quot;sum&amp;quot; csum :: &lt;span class=&quot;dt&quot;&gt;Ptr&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;List&lt;/span&gt; -&amp;gt; &lt;span class=&quot;dt&quot;&gt;Int&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The Haskell FFI explicitly allows both declarations, and it may seem
that a function summing up numbers deserves to be pure.&lt;/p&gt;
&lt;p&gt;However, declaring &lt;code&gt;csum&lt;/code&gt; as pure would break every single
example above (after making the trivial changes to make it type check).
Can you see why?&lt;/p&gt;
&lt;p&gt;The answer is laziness. If we made &lt;code&gt;csum&lt;/code&gt; pure and naively
changed our code to compile, we might arrive at something like&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb16&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb16-1&quot;&gt;&lt;a href=&quot;#cb16-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;bracket (mkList [&lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;..&lt;/span&gt;n]) freeList (&lt;span class=&quot;fu&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt; csum)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This tells the compiler to:&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;Call &lt;code&gt;mkList [1..n]&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;Pass the result to the pure &lt;code&gt;csum&lt;/code&gt; function, and promote
the value to the &lt;code&gt;IO&lt;/code&gt; type;&lt;/li&gt;
&lt;li&gt;Call &lt;code&gt;freeList&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;Return the value from step (2).&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;You may think that the value returned from step (2), and therefore
from the whole expression, is a number — the length of the list. But
because of laziness, it’s not a number yet. It is a thunk, a delayed
application of &lt;code&gt;csum&lt;/code&gt; to the pointer value. This thunk will
be forced at the next step — when we pass it to the &lt;code&gt;print&lt;/code&gt;
function, for example, or compare it with the expected value. Only then
will &lt;code&gt;csum&lt;/code&gt; try to do its work. But it will be too late,
because by that time &lt;code&gt;freeList&lt;/code&gt; will have run, and
&lt;code&gt;csum&lt;/code&gt; will discover that its pointer argument is no longer a
valid pointer.&lt;/p&gt;
&lt;p&gt;To work around this problem, we could replace &lt;code&gt;return&lt;/code&gt;
with &lt;code&gt;evaluate&lt;/code&gt;, but this just shows us that our decision to
declare &lt;code&gt;csum&lt;/code&gt; was a mistake. It matters in what order
&lt;code&gt;mkList&lt;/code&gt;, &lt;code&gt;csum&lt;/code&gt;, and &lt;code&gt;freeList&lt;/code&gt; are
evaluated, and the principled way to enforce this order in Haskell is
the &lt;code&gt;IO&lt;/code&gt; monad.&lt;/p&gt;
&lt;h2 id=&quot;benchmark-results&quot;&gt;Benchmark results&lt;/h2&gt;
&lt;p&gt;The benchmark consists of allocating, summing, and deallocating a
list of numbers from 1 to 100.&lt;/p&gt;
&lt;figure&gt;
&lt;img src=&quot;/img/malloc-hs-bench.svg&quot;&gt;&lt;img src=&quot;/img/malloc-hs-bench-noway3.svg&quot;&gt;
&lt;/figure&gt;
&lt;pre&gt;&lt;code&gt;benchmarking way1
time                 3.301 μs   (3.277 μs .. 3.345 μs)
                     0.999 R²   (0.998 R² .. 1.000 R²)
mean                 3.305 μs   (3.288 μs .. 3.341 μs)
std dev              76.34 ns   (44.80 ns .. 142.3 ns)
variance introduced by outliers: 27% (moderately inflated)

benchmarking way2
time                 2.183 μs   (2.147 μs .. 2.227 μs)
                     0.998 R²   (0.997 R² .. 1.000 R²)
mean                 2.161 μs   (2.145 μs .. 2.185 μs)
std dev              65.91 ns   (46.76 ns .. 97.04 ns)
variance introduced by outliers: 40% (moderately inflated)

benchmarking way3
time                 13.21 μs   (12.92 μs .. 13.49 μs)
                     0.997 R²   (0.996 R² .. 0.998 R²)
mean                 12.74 μs   (12.59 μs .. 12.93 μs)
std dev              574.0 ns   (437.5 ns .. 751.6 ns)
variance introduced by outliers: 54% (severely inflated)

benchmarking way4
time                 1.580 μs   (1.560 μs .. 1.605 μs)
                     0.999 R²   (0.998 R² .. 0.999 R²)
mean                 1.582 μs   (1.570 μs .. 1.601 μs)
std dev              51.28 ns   (37.48 ns .. 72.14 ns)
variance introduced by outliers: 44% (moderately inflated)

benchmarking way5
time                 1.434 μs   (1.418 μs .. 1.459 μs)
                     0.998 R²   (0.997 R² .. 0.998 R²)
mean                 1.511 μs   (1.487 μs .. 1.538 μs)
std dev              83.96 ns   (72.68 ns .. 95.63 ns)
variance introduced by outliers: 70% (severely inflated)

benchmarking way6
time                 2.155 μs   (2.135 μs .. 2.178 μs)
                     0.999 R²   (0.999 R² .. 1.000 R²)
mean                 2.152 μs   (2.139 μs .. 2.171 μs)
std dev              52.54 ns   (40.20 ns .. 69.02 ns)
variance introduced by outliers: 30% (moderately inflated)&lt;/code&gt;&lt;/pre&gt;
</description>
                        <pubDate>Sun, 06 Aug 2017 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2017-08-06-manage-allocated-memory-haskell</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2017-08-06-manage-allocated-memory-haskell.html</guid>
                </item>
        
                <item>
                        <title>Haskell library in a C project</title>
                        <description>&lt;p&gt;Haskell FFI (Foreign Function Interface) lets us call C code from
Haskell and Haskell code from C.&lt;/p&gt;
&lt;p&gt;Usually, people are more interested in calling C libraries from
Haskell than vice versa. This is how we have bindings to operating
systems (like POSIX and Windows APIs), graphics libraries (like GTK and
Qt), and highly optimized code (like BLAS or ICU).&lt;/p&gt;
&lt;p&gt;But at &lt;a href=&quot;https://nstack.com/&quot;&gt;NStack&lt;/a&gt;, we are going in the
opposite direction. We want to build a Haskell library that is going to
be used by the programming languages that we support, such as
Python.&lt;/p&gt;
&lt;p&gt;Several places on the internet explain how to write FFI export
declarations and initialize the GHC RTS from C: &lt;a
href=&quot;https://downloads.haskell.org/~ghc/8.0.2/docs/html/users_guide/ffi-chap.html#making-a-haskell-library-that-can-be-called-from-foreign-code&quot;&gt;the
GHC manual&lt;/a&gt;, &lt;a
href=&quot;https://wiki.haskell.org/Foreign_Function_Interface#Exported_functions&quot;&gt;the
Haskell wiki&lt;/a&gt;, and &lt;a
href=&quot;https://github.com/ifesdjeen/haskell-ffi-tutorial&quot;&gt;a tutorial by
Alex Petrov&lt;/a&gt; among others.&lt;/p&gt;
&lt;p&gt;But none of them address the elephant in the room: how do you turn
your Haskell code into a library? You know, an &lt;code&gt;.so&lt;/code&gt; file
that you can pass to a linker or load with &lt;code&gt;dlopen&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;This may seem like a trivial matter, so let’s review what exactly
makes it complicated.&lt;/p&gt;
&lt;p&gt;When ghc compiles a Haskell package that contains a library, by
default it will produce both a dynamic (&lt;code&gt;.so&lt;/code&gt;) and a static
(&lt;code&gt;.a&lt;/code&gt;) library. The dynamic libraries are used to execute
Template Haskell code, while the static libaries are used when linking
the final executable (again, by default).&lt;/p&gt;
&lt;p&gt;These libraries are scattered around the file system, e.g.:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;~/.stack/programs/x86_64-linux/ghc-8.0.2/lib/ghc-8.0.2/deepseq-1.4.2.0/libHSdeepseq-1.4.2.0-ghc8.0.2.so&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;~/.stack/snapshots/x86_64-linux/lts-8.11/8.0.2/lib/x86_64-linux-ghc-8.0.2/libHSwai-3.2.1.1-9yigkTgtHNLHh2mXrnIXo-ghc8.0.2.so&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;.stack-work/dist/x86_64-linux/Cabal-1.24.2.0/build/libHStasty-0.11.2.1-4ogqtS3RxMEH205xhabqo-ghc8.0.2.so&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;A typical Haskell package will have hundreds of transitive
dependencies, all of which you need to give to the linker. Furthermore,
they need to come in the right (reverse topological) order.&lt;/p&gt;
&lt;p&gt;Much of this complexity is managed by stack, cabal-install, or
&lt;code&gt;ghc --make&lt;/code&gt;, so you don’t notice it. Additionally, since by
default Haskell depedencies are linked statically, you don’t have to
worry about distributing them.&lt;/p&gt;
&lt;p&gt;But these tools are designed to build executables, not shared
objects, and I couldn’t make them do what I needed.&lt;/p&gt;
&lt;p&gt;So I’ve written a &lt;a
href=&quot;/files/2017-07-26-haskell-library-in-c-project/opts.pl&quot;&gt;perl
script&lt;/a&gt; that does the following:&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;constructs the package dependency graph by repeatedly calling
&lt;code&gt;ghc-pkg field&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;collects all compilation and linking options and writes them to two
files, &lt;code&gt;incopts.txt&lt;/code&gt; (“inc” stands for “include”) and
&lt;code&gt;ldopts.txt&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;creates a &lt;code&gt;lib&lt;/code&gt; directory and symlinks all the relevant
&lt;code&gt;.so&lt;/code&gt; files there so that they can be easily
distributed.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Because the script uses the low-level &lt;code&gt;ghc-pkg&lt;/code&gt; command,
it can be used in any Haskell environment — be it stack, cabal-install,
or even pure ghc. For instance, to use it with stack, I run&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;stack exec perl opts.pl libnstack&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here are a few things I’ve learned along the way while writing the
script, for your education or amusement:&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;&lt;p&gt;Each package has two library locations associated with it:
&lt;code&gt;library-dirs&lt;/code&gt; and &lt;code&gt;dynamic-library-dirs&lt;/code&gt;. Except
the &lt;code&gt;rts&lt;/code&gt; package, which only has &lt;code&gt;library-dirs&lt;/code&gt;
containing both static and dynamic libraries.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The libraries listed in &lt;code&gt;hs-libraries&lt;/code&gt; are divided
into “Haskell” and “C” libraries. Their library names start with
&lt;code&gt;HS&lt;/code&gt; and &lt;code&gt;C&lt;/code&gt;, respectively. The division has
nothing to do with the language used to produce a library, because the
rts, which is written in C, has the name &lt;code&gt;HSrts&lt;/code&gt;. The way I
understand it is that “Haskell” libraries differ among the ghc versions,
while “C” libraries usually don’t. The only example of a “C” library is
currently &lt;code&gt;Cffi&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Why is &lt;code&gt;libffi&lt;/code&gt; in &lt;code&gt;hs-libraries&lt;/code&gt; and not in
&lt;code&gt;extra-libraries&lt;/code&gt;, together with &lt;code&gt;libgmp&lt;/code&gt;,
&lt;code&gt;libm&lt;/code&gt; etc.? My guess is, to link it statically by
default.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The &lt;code&gt;hs-libraries&lt;/code&gt; field of the package description
gives the static library name. To get the dynamic library name of a
“Haskell” library, append &lt;code&gt;-ghc8.0.2&lt;/code&gt; (substitute your
compiler version).&lt;/p&gt;
&lt;p&gt;To get the dynamic library name of a “C” library (&lt;code&gt;Cffi&lt;/code&gt;),
strip that &lt;code&gt;C&lt;/code&gt;. As the comment in
&lt;code&gt;compiler/main/Packages.hs&lt;/code&gt; explains:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt; -- For non-Haskell libraries, we use the name &amp;quot;Cfoo&amp;quot;. The .a
 -- file is libCfoo.a, and the .so is libfoo.so. That way the
 -- linker knows what we mean for the vanilla (-lCfoo) and dyn
 -- (-lfoo) ways.&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Make sure you are linking against the threaded RTS, or else your
signals won’t be handled properly, and an innocent Ctrl-C will likely
result in a segfault. To link against the threaded RTS, replace
&lt;code&gt;HSrts&lt;/code&gt; with &lt;code&gt;HSrts_thr&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;HSrts&lt;/code&gt; is not the only library that has a
&lt;code&gt;_thr&lt;/code&gt; version; there’s also &lt;code&gt;libCffi_thr.a&lt;/code&gt;, but
it is identical to &lt;code&gt;libCffi.a&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;We’ve paid quite a bit of attention to &lt;code&gt;libCffi&lt;/code&gt;, but
it’s probably not even used on the major platforms like x86 or x86_64.
See &lt;code&gt;rts/Adjustor.c&lt;/code&gt; and &lt;code&gt;mk/config.mk&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;There’s a field for linker options, called
&lt;code&gt;ld-options&lt;/code&gt;, which is apparently only used by the
&lt;code&gt;rts&lt;/code&gt; package. It contains a bunch of flags like&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;-Wl,-u,base_GHCziTopHandler_runNonIO_closure
-Wl,-u,ghczmprim_GHCziTypes_Czh_con_info
-Wl,-u,base_GHCziInt_I8zh_static_info
...&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I haven’t yet figured out what they do and why they are
needed.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Thanks to &lt;a href=&quot;https://bgamari.github.io/&quot;&gt;Ben Gamari&lt;/a&gt; for
answering some of my questions on IRC and &lt;a
href=&quot;https://github.com/edwardgeorge&quot;&gt;Edward George&lt;/a&gt; for helping to
debug the script.&lt;/p&gt;
&lt;h2 id=&quot;note-on-cabals-foreign-libraries&quot;&gt;Note on Cabal’s foreign
libraries&lt;/h2&gt;
&lt;p&gt;&lt;a
href=&quot;https://twitter.com/refold/status/890680642962415616&quot;&gt;Mikhail
Glushenkov points out&lt;/a&gt; that, starting from Cabal 2.0, you can use a
&lt;a
href=&quot;https://cabal.readthedocs.io/en/latest/developing-packages.html#foreign-libraries&quot;&gt;&lt;code&gt;foreign-library&lt;/code&gt;&lt;/a&gt;
component in a cabal file instead of the usual &lt;code&gt;library&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;While this feature is definitely an improvement, it doesn’t seem to
address the issues described above and solved by my Perl script:&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;Link the resulting library using gcc or ld (not ghc).&lt;/li&gt;
&lt;li&gt;Distribute the Haskell foreign library together with its
dependencies.&lt;/li&gt;
&lt;/ol&gt;
</description>
                        <pubDate>Wed, 26 Jul 2017 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2017-07-26-haskell-library-in-c-project</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2017-07-26-haskell-library-in-c-project.html</guid>
                </item>
        
                <item>
                        <title>Linux audio recording guide (PulseAudio or PipeWire)</title>
                        <description>&lt;p&gt;This article explains how to record an audio stream on a Linux system
running either PulseAudio or PipeWire. (The commands below are all
PulseAudio commands, but they should work on a PipeWire system thanks to
its PulseAudio compatibility.)&lt;/p&gt;
&lt;p&gt;You can record both input streams (microphones) and output streams
(whatever you are hearing in your headphones). However, each stream goes
to a separate file. If you want to record a conversation, record both
streams and mix them afterwards in an audio editor/DAW.&lt;/p&gt;
&lt;p&gt;First, find out the PulseAudio name of the stream you want to
record.&lt;/p&gt;
&lt;p&gt;If you want to record a microphone, run&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;pactl --format=json list sources | jq &amp;#39;.[] | select(.monitor_source == &amp;quot;&amp;quot;) | {name: .name, desc: .description}&amp;#39;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here is an example output:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
  &amp;quot;name&amp;quot;: &amp;quot;alsa_input.pci-0000_06_00.6.analog-stereo&amp;quot;,
  &amp;quot;desc&amp;quot;: &amp;quot;Family 17h/19h HD Audio Controller Analog Stereo&amp;quot;
}
{
  &amp;quot;name&amp;quot;: &amp;quot;alsa_input.usb-Audient_EVO4-00.analog-surround-40&amp;quot;,
  &amp;quot;desc&amp;quot;: &amp;quot;EVO4 Analog Surround 4.0&amp;quot;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The &lt;code&gt;&quot;name&quot;&lt;/code&gt; component is what you need; the description
is just there to help you figure out which stream is the right one.&lt;/p&gt;
&lt;p&gt;If you want to record an output (e.g. a person you’re talking to),
similarly run&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;pactl --format=json list sources | jq &amp;#39;.[] | select(.monitor_source != &amp;quot;&amp;quot;) | {name: .name, desc: .description}&amp;#39;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Once you know the name of the stream you want to record, run&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;parecord --channels=1 --file-format=flac --device $STREAM_NAME filename.flac&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When you are done recording, terminate the process by pressing
&lt;code&gt;Ctrl-C&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;--channels=1&lt;/code&gt; forces your recording to mono, which is
usually what you want.&lt;/p&gt;
&lt;p&gt;To see the list of supported file formats, run&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;parecord --list-file-formats&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If you try to record a generic output, such as
&lt;code&gt;alsa_output.pci-0000_06_00.6.analog-stereo.monitor&lt;/code&gt;, you
might also capture some unwanted output from other applications or
notification sounds. To make sure only a specific application is
recorded, here’s what you can do:&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;Create a fresh sink that will send its input to headphones, but to
which no application is connected by default.&lt;/li&gt;
&lt;li&gt;Direct the sound from the specific applications you want to record
into this new sink.&lt;/li&gt;
&lt;li&gt;Record the output of the new sink.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Find out the name of your output device by running&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;pactl --format=json list sinks | jq &amp;#39;.[] | {name: .name, desc: .description}&amp;#39;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In my case, it says&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
  &amp;quot;name&amp;quot;: &amp;quot;alsa_output.pci-0000_06_00.6.analog-stereo&amp;quot;,
  &amp;quot;desc&amp;quot;: &amp;quot;Family 17h/19h HD Audio Controller Analog Stereo&amp;quot;
}
{
  &amp;quot;name&amp;quot;: &amp;quot;alsa_output.usb-Audient_EVO4-00.analog-surround-40&amp;quot;,
  &amp;quot;desc&amp;quot;: &amp;quot;EVO4 Analog Surround 4.0&amp;quot;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Let’s say my headphones are connected to EVO 4. Then I would run:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;OUTPUT_NAME=alsa_output.usb-Audient_EVO4-00.analog-surround-40
pactl load-module module-combine-sink sink_name=recording sink_properties=device.description=Recording slaves=$OUTPUT_NAME
parecord --channels=1 --file-format=flac --device recording.monitor filename.flac&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, redirect the sound to the Recording sink:&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;Run the &lt;code&gt;pavucontrol&lt;/code&gt; command (a graphical window will
appear) and go to the “Playback” tab.&lt;/li&gt;
&lt;li&gt;Start the application you’d like to record.&lt;/li&gt;
&lt;li&gt;The application should appear in &lt;code&gt;pavucontrol&lt;/code&gt;. If it
doesn’t, make sure the application produces some sound. Unfortunately,
until the application tries to play something, PulseAudio/PipeWire
cannot “see” it.&lt;/li&gt;
&lt;li&gt;Choose the &lt;code&gt;Recording&lt;/code&gt; sink for the application as shown
on the screenshot:&lt;/li&gt;
&lt;/ol&gt;
&lt;figure&gt;
&lt;img src=&quot;/img/pavucontrol.png&quot;
alt=&quot;A screenshot of a pavucontrol window&quot; /&gt;
&lt;figcaption aria-hidden=&quot;true&quot;&gt;A screenshot of a pavucontrol
window&lt;/figcaption&gt;
&lt;/figure&gt;
</description>
                        <pubDate>Fri, 21 Jul 2017 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2017-07-21-record-audio-linux</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2017-07-21-record-audio-linux.html</guid>
                </item>
        
                <item>
                        <title>All vk.com IP addresses</title>
                        <description>&lt;p&gt;Here’s the current list of IP addresses owned by the social network
&lt;a href=&quot;https://vk.com&quot;&gt;vk.com&lt;/a&gt; (“vkontakte”/“Вконтакте”):&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style=&quot;text-align: left;&quot;&gt;CIDR&lt;/th&gt;
&lt;th&gt;Base address&lt;/th&gt;
&lt;th style=&quot;text-align: left;&quot;&gt;Netmask&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: left;&quot;&gt;87.240.128.0/18&lt;/td&gt;
&lt;td&gt;87.240.128.0&lt;/td&gt;
&lt;td style=&quot;text-align: left;&quot;&gt;255.255.192.0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: left;&quot;&gt;93.186.224.0/20&lt;/td&gt;
&lt;td&gt;93.186.224.0&lt;/td&gt;
&lt;td style=&quot;text-align: left;&quot;&gt;255.255.240.0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: left;&quot;&gt;95.142.192.0/20&lt;/td&gt;
&lt;td&gt;95.142.192.0&lt;/td&gt;
&lt;td style=&quot;text-align: left;&quot;&gt;255.255.240.0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: left;&quot;&gt;95.213.0.0/17&lt;/td&gt;
&lt;td&gt;95.213.0.0&lt;/td&gt;
&lt;td style=&quot;text-align: left;&quot;&gt;255.255.128.0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: left;&quot;&gt;185.32.248.0/22&lt;/td&gt;
&lt;td&gt;185.32.248.0&lt;/td&gt;
&lt;td style=&quot;text-align: left;&quot;&gt;255.255.252.0&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;You can use this list to block, unblock, or apply custom routing to
the VK traffic.&lt;/p&gt;
&lt;p&gt;Here is the Perl script I wrote to extract this information, in case
you want to check whether this table is up-to-date or generate a similar
table for a different website/company.&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb1&quot;&gt;&lt;pre
class=&quot;sourceCode perl&quot;&gt;&lt;code class=&quot;sourceCode perl&quot;&gt;&lt;span id=&quot;cb1-1&quot;&gt;&lt;a href=&quot;#cb1-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;#!/usr/bin/perl -l&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-2&quot;&gt;&lt;a href=&quot;#cb1-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-3&quot;&gt;&lt;a href=&quot;#cb1-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;fu&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;strict&lt;/span&gt;;&lt;/span&gt;
&lt;span id=&quot;cb1-4&quot;&gt;&lt;a href=&quot;#cb1-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;fu&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;warnings&lt;/span&gt;;&lt;/span&gt;
&lt;span id=&quot;cb1-5&quot;&gt;&lt;a href=&quot;#cb1-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;fu&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;Net::Netmask&lt;/span&gt;;&lt;/span&gt;
&lt;span id=&quot;cb1-6&quot;&gt;&lt;a href=&quot;#cb1-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-7&quot;&gt;&lt;a href=&quot;#cb1-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;my&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;@inetnum&lt;/span&gt;;&lt;/span&gt;
&lt;span id=&quot;cb1-8&quot;&gt;&lt;a href=&quot;#cb1-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;my&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;@ranges&lt;/span&gt;;&lt;/span&gt;
&lt;span id=&quot;cb1-9&quot;&gt;&lt;a href=&quot;#cb1-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-10&quot;&gt;&lt;a href=&quot;#cb1-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;while&lt;/span&gt; (&amp;lt;&amp;gt;) {&lt;/span&gt;
&lt;span id=&quot;cb1-11&quot;&gt;&lt;a href=&quot;#cb1-11&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;if&lt;/span&gt; (&lt;span class=&quot;ot&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;ch&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;ot&quot;&gt;inetnum:&lt;/span&gt;&lt;span class=&quot;bn&quot;&gt;\s&lt;/span&gt;&lt;span class=&quot;ch&quot;&gt;*(&lt;/span&gt;&lt;span class=&quot;bn&quot;&gt;\S&lt;/span&gt;&lt;span class=&quot;ch&quot;&gt;+)&lt;/span&gt;&lt;span class=&quot;ot&quot;&gt; - &lt;/span&gt;&lt;span class=&quot;ch&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bn&quot;&gt;\S&lt;/span&gt;&lt;span class=&quot;ch&quot;&gt;+)$&lt;/span&gt;&lt;span class=&quot;ot&quot;&gt;/&lt;/span&gt;) { &lt;span class=&quot;dt&quot;&gt;@inetnum&lt;/span&gt; = (&lt;span class=&quot;wa&quot;&gt;$1&lt;/span&gt;,&lt;span class=&quot;wa&quot;&gt;$2&lt;/span&gt;); }&lt;/span&gt;
&lt;span id=&quot;cb1-12&quot;&gt;&lt;a href=&quot;#cb1-12&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;if&lt;/span&gt; (&lt;span class=&quot;ot&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;ch&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;ot&quot;&gt;mnt-by:&lt;/span&gt;&lt;span class=&quot;bn&quot;&gt;\s&lt;/span&gt;&lt;span class=&quot;ch&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;ot&quot;&gt;VKONTAKTE-NET-MNT&lt;/span&gt;&lt;span class=&quot;ch&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;ot&quot;&gt;/&lt;/span&gt;) {&lt;/span&gt;
&lt;span id=&quot;cb1-13&quot;&gt;&lt;a href=&quot;#cb1-13&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;fu&quot;&gt;push&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;@ranges&lt;/span&gt;, range2cidrlist(&lt;span class=&quot;dt&quot;&gt;@inetnum&lt;/span&gt;);&lt;/span&gt;
&lt;span id=&quot;cb1-14&quot;&gt;&lt;a href=&quot;#cb1-14&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  }&lt;/span&gt;
&lt;span id=&quot;cb1-15&quot;&gt;&lt;a href=&quot;#cb1-15&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;}&lt;/span&gt;
&lt;span id=&quot;cb1-16&quot;&gt;&lt;a href=&quot;#cb1-16&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-17&quot;&gt;&lt;a href=&quot;#cb1-17&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;my&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;$cidr&lt;/span&gt; (cidrs2cidrs(&lt;span class=&quot;dt&quot;&gt;@ranges&lt;/span&gt;)) {&lt;/span&gt;
&lt;span id=&quot;cb1-18&quot;&gt;&lt;a href=&quot;#cb1-18&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;fu&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;$cidr&lt;/span&gt;, &lt;span class=&quot;ot&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;ch&quot;&gt;\t&lt;/span&gt;&lt;span class=&quot;ot&quot;&gt;&amp;quot;&lt;/span&gt;, &lt;span class=&quot;dt&quot;&gt;$cidr&lt;/span&gt;-&amp;gt;&lt;span class=&quot;dt&quot;&gt;base&lt;/span&gt;(), &lt;span class=&quot;ot&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;ch&quot;&gt;\t&lt;/span&gt;&lt;span class=&quot;ot&quot;&gt;&amp;quot;&lt;/span&gt;, &lt;span class=&quot;dt&quot;&gt;$cidr&lt;/span&gt;-&amp;gt;&lt;span class=&quot;dt&quot;&gt;mask&lt;/span&gt;();&lt;/span&gt;
&lt;span id=&quot;cb1-19&quot;&gt;&lt;a href=&quot;#cb1-19&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Usage (if you saved the script as &lt;code&gt;ip_ranges.pl&lt;/code&gt;):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;wget ftp://ftp.ripe.net/ripe/dbase/split/ripe.db.inetnum.gz
zcat ripe.db.inetnum.gz | perl ip_ranges.pl&lt;/code&gt;&lt;/pre&gt;
</description>
                        <pubDate>Fri, 14 Jul 2017 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2017-07-14-all-vk.com-ip-addresses</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2017-07-14-all-vk.com-ip-addresses.html</guid>
                </item>
        
                <item>
                        <title>Can probability be greater than one?</title>
                        <description>&lt;p&gt;&lt;strong&gt;Disclaimer:&lt;/strong&gt; don’t take this article too seriously.
Obviously, a probability greater than one violates many properties of
probability (including Kolmogorov’s axioms), and the reasoning here is
far from rigorous. I wrote this partly as a joke, partly as food for
thought. I do think, however, that this line of reasoning has something
to it and could probably be formalized by someone who has more
motivation.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;Have you ever wondered whether a probability could equal, say, 2?&lt;/p&gt;
&lt;p&gt;The (frequentist) definition of probability is the limit of the ratio
between the number of successes, &lt;span
class=&quot;math inline&quot;&gt;\(N_s\)&lt;/span&gt;, and the number of trials, &lt;span
class=&quot;math inline&quot;&gt;\(N\)&lt;/span&gt;:&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;math display&quot;&gt;\[
p = \lim_{N\to\infty}\frac{N_s}N
\]&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;If the number of successes is allowed to be higher than the number of
trials, then nothing prevents &lt;span class=&quot;math inline&quot;&gt;\(p\)&lt;/span&gt;
from exceeding 1.&lt;/p&gt;
&lt;p&gt;Consider, for instance, the &lt;a
href=&quot;https://en.wikipedia.org/wiki/Sleeping_Beauty_problem&quot;&gt;sleeping
beauty problem&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Sleeping Beauty volunteers to undergo the following experiment and is
told all of the following details: On Sunday she will be put to sleep.
Once or twice, during the experiment, Beauty will be awakened,
interviewed, and put back to sleep with an amnesia-inducing drug that
makes her forget that awakening. A fair coin will be tossed to determine
which experimental procedure to undertake: if the coin comes up heads,
Beauty will be awakened and interviewed on Monday only. If the coin
comes up tails, she will be awakened and interviewed on Monday and
Tuesday. In either case, she will be awakened on Wednesday without
interview and the experiment ends.&lt;/p&gt;
&lt;p&gt;Any time Sleeping Beauty is awakened and interviewed she will not be
able to tell which day it is or whether she has been awakened before.
During the interview Beauty is asked: “What is your credence now for the
proposition that the coin landed heads?”.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;See also &lt;a href=&quot;https://www.youtube.com/watch?v=zL52lG6aNIY&quot;&gt;this
video&lt;/a&gt; by Julia Galef, from which I originally found out about this
problem.&lt;/p&gt;
&lt;p&gt;Denote the events of the coin landing heads as &lt;span
class=&quot;math inline&quot;&gt;\(H\)&lt;/span&gt;, the coin landing tails as &lt;span
class=&quot;math inline&quot;&gt;\(T\)&lt;/span&gt;, and Beauty wakening up and being
interviewed as &lt;span class=&quot;math inline&quot;&gt;\(I\)&lt;/span&gt;. Then the problem
lies in finding the conditional probability &lt;span
class=&quot;math inline&quot;&gt;\(p(H|I)\)&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;Conditional probability problems of this kind are solved by the Bayes
theorem:&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;math display&quot;&gt;\[
p(H|I)=\frac{p(I|H)p(H)}{p(I|H)p(H)+p(I|T)p(T)}
\]&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;The prior probabilities &lt;span class=&quot;math inline&quot;&gt;\(p(H)\)&lt;/span&gt; and
&lt;span class=&quot;math inline&quot;&gt;\(p(T)\)&lt;/span&gt; equal &lt;span
class=&quot;math inline&quot;&gt;\(1/2\)&lt;/span&gt; for a fair coin, so&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;math display&quot;&gt;\[
p(H|I)=\frac{p(I|H)}{p(I|H)+p(I|T)}.
\]&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;The probability &lt;span class=&quot;math inline&quot;&gt;\(p(I|H)\)&lt;/span&gt; of Beauty
being interviewed under heads is 1: it happens with certainty.&lt;/p&gt;
&lt;p&gt;But if the coin comes up tails, the interviewing happens twice as
many times. Every time the experiment is conducted and the coin lands
tails, the event &lt;span class=&quot;math inline&quot;&gt;\(I\)&lt;/span&gt; occurs two
times. The only logical possibility is to assign &lt;span
class=&quot;math inline&quot;&gt;\(p(I|T)\)&lt;/span&gt; the value of 2.&lt;/p&gt;
&lt;p&gt;Therefore,&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;math display&quot;&gt;\[
p(H|I)=\frac{1}{1+2}=1/3.
\]&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;I guess I’m a thirder then.&lt;/p&gt;
</description>
                        <pubDate>Fri, 30 Jun 2017 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2017-06-30-probability-greater-than-one</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2017-06-30-probability-greater-than-one.html</guid>
                </item>
        
                <item>
                        <title>Generic unification</title>
                        <description>&lt;p&gt;The &lt;a
href=&quot;https://hackage.haskell.org/package/unification-fd&quot;&gt;unification-fd&lt;/a&gt;
package by &lt;a href=&quot;http://code.haskell.org/~wren/&quot;&gt;wren gayle
romano&lt;/a&gt; is the de-facto standard way to do unification in Haskell.
You’d use it if you need to implement type inference for your DSL, for
example.&lt;/p&gt;
&lt;p&gt;To use unification-fd, we first need to express our &lt;code&gt;Type&lt;/code&gt;
type as a fixpoint of a functor, a.k.a. an &lt;a
href=&quot;https://www.schoolofhaskell.com/user/bartosz/understanding-algebras&quot;&gt;initial
algebra&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;For instance, let’s say we want to implement type inference for the
simply typed lambda calculus (STLC). The types in STLC can be
represented by a Haskell type&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb1&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb1-1&quot;&gt;&lt;a href=&quot;#cb1-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Type&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;BaseType&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;String&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-2&quot;&gt;&lt;a href=&quot;#cb1-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;          &lt;span class=&quot;op&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Fun&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Type&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Type&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Note that &lt;code&gt;Type&lt;/code&gt; cannot represent type variables.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Type&lt;/code&gt; can be equivalently represented as a fixpoint of a
functor, &lt;code&gt;TypeF&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb2&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb2-1&quot;&gt;&lt;a href=&quot;#cb2-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;co&quot;&gt;-- defined in Data.Functor.Fixedpoint in unification-fd&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-2&quot;&gt;&lt;a href=&quot;#cb2-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;newtype&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Fix&lt;/span&gt; f &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Fix&lt;/span&gt; {&lt;span class=&quot;ot&quot;&gt; unFix ::&lt;/span&gt; f (&lt;span class=&quot;dt&quot;&gt;Fix&lt;/span&gt; f) }&lt;/span&gt;
&lt;span id=&quot;cb2-3&quot;&gt;&lt;a href=&quot;#cb2-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-4&quot;&gt;&lt;a href=&quot;#cb2-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;TypeF&lt;/span&gt; a &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;BaseType&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;String&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-5&quot;&gt;&lt;a href=&quot;#cb2-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;             &lt;span class=&quot;op&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Fun&lt;/span&gt; a a&lt;/span&gt;
&lt;span id=&quot;cb2-6&quot;&gt;&lt;a href=&quot;#cb2-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;deriving&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;Functor&lt;/span&gt;, &lt;span class=&quot;dt&quot;&gt;Foldable&lt;/span&gt;, &lt;span class=&quot;dt&quot;&gt;Traversable&lt;/span&gt;)&lt;/span&gt;
&lt;span id=&quot;cb2-7&quot;&gt;&lt;a href=&quot;#cb2-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-8&quot;&gt;&lt;a href=&quot;#cb2-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Type&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Fix&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;TypeF&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;So &lt;code&gt;Fix TypeF&lt;/code&gt; still cannot represent any type variables,
but &lt;code&gt;UTerm TypeF&lt;/code&gt; can. &lt;code&gt;UTerm&lt;/code&gt; is another type
defined in &lt;code&gt;unification-fd&lt;/code&gt; that is similar to
&lt;code&gt;Fix&lt;/code&gt; except it includes another constructor for type
variables:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb3&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb3-1&quot;&gt;&lt;a href=&quot;#cb3-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;co&quot;&gt;-- defined in Control.Unification in unification-fd&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-2&quot;&gt;&lt;a href=&quot;#cb3-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;UTerm&lt;/span&gt; t v&lt;/span&gt;
&lt;span id=&quot;cb3-3&quot;&gt;&lt;a href=&quot;#cb3-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;UVar&lt;/span&gt;  &lt;span class=&quot;op&quot;&gt;!&lt;/span&gt;v               &lt;span class=&quot;co&quot;&gt;-- ^ A unification variable.&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-4&quot;&gt;&lt;a href=&quot;#cb3-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;op&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;UTerm&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;!&lt;/span&gt;(t (&lt;span class=&quot;dt&quot;&gt;UTerm&lt;/span&gt; t v)) &lt;span class=&quot;co&quot;&gt;-- ^ Some structure containing subterms.&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-5&quot;&gt;&lt;a href=&quot;#cb3-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-6&quot;&gt;&lt;a href=&quot;#cb3-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;PolyType&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;UTerm&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;TypeF&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;IntVar&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;UTerm&lt;/code&gt;, by the way, is the free monad over the functor
&lt;code&gt;t&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&quot;unifiable&quot;&gt;Unifiable&lt;/h2&gt;
&lt;p&gt;The &lt;code&gt;Control.Unification&lt;/code&gt; module exposes several
algorithms (unification, alpha equivalence) that work on any
&lt;code&gt;UTerm&lt;/code&gt;, provided that the underlying functor &lt;code&gt;t&lt;/code&gt;
(&lt;code&gt;TypeF&lt;/code&gt; in our example) implements a &lt;code&gt;zipMatch&lt;/code&gt;
function:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb4&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb4-1&quot;&gt;&lt;a href=&quot;#cb4-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;class&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;Traversable&lt;/span&gt; t) &lt;span class=&quot;ot&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Unifiable&lt;/span&gt; t &lt;span class=&quot;kw&quot;&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-2&quot;&gt;&lt;a href=&quot;#cb4-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;co&quot;&gt;-- | Perform one level of equality testing for terms. If the&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-3&quot;&gt;&lt;a href=&quot;#cb4-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;co&quot;&gt;-- term constructors are unequal then return @Nothing@; if they&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-4&quot;&gt;&lt;a href=&quot;#cb4-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;co&quot;&gt;-- are equal, then return the one-level spine filled with&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-5&quot;&gt;&lt;a href=&quot;#cb4-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;co&quot;&gt;-- resolved subterms and\/or pairs of subterms to be recursively&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-6&quot;&gt;&lt;a href=&quot;#cb4-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;co&quot;&gt;-- checked.&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-7&quot;&gt;&lt;a href=&quot;#cb4-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;    zipMatch ::&lt;/span&gt; t a &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; t a &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Maybe&lt;/span&gt; (t (&lt;span class=&quot;dt&quot;&gt;Either&lt;/span&gt; a (a,a)))&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;zipMatch&lt;/code&gt; essentially tells the algorithms which
constructors of our &lt;code&gt;TypeF&lt;/code&gt; functor are the same, which are
different, and which fields correspond to variables. So for
&lt;code&gt;TypeF&lt;/code&gt; it could look like&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb5&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb5-1&quot;&gt;&lt;a href=&quot;#cb5-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;instance&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Unifiable&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;TypeF&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-2&quot;&gt;&lt;a href=&quot;#cb5-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  zipMatch (&lt;span class=&quot;dt&quot;&gt;BaseType&lt;/span&gt; a) (&lt;span class=&quot;dt&quot;&gt;BaseType&lt;/span&gt; b) &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-3&quot;&gt;&lt;a href=&quot;#cb5-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;kw&quot;&gt;if&lt;/span&gt; a &lt;span class=&quot;op&quot;&gt;==&lt;/span&gt; b&lt;/span&gt;
&lt;span id=&quot;cb5-4&quot;&gt;&lt;a href=&quot;#cb5-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;kw&quot;&gt;then&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Just&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;BaseType&lt;/span&gt; a&lt;/span&gt;
&lt;span id=&quot;cb5-5&quot;&gt;&lt;a href=&quot;#cb5-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;kw&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Nothing&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-6&quot;&gt;&lt;a href=&quot;#cb5-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  zipMatch (&lt;span class=&quot;dt&quot;&gt;Fun&lt;/span&gt; a1 a2) (&lt;span class=&quot;dt&quot;&gt;Fun&lt;/span&gt; b1 b2) &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-7&quot;&gt;&lt;a href=&quot;#cb5-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;dt&quot;&gt;Just&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Fun&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;Right&lt;/span&gt; (a1, b1)) (&lt;span class=&quot;dt&quot;&gt;Right&lt;/span&gt; (a2, b2))&lt;/span&gt;
&lt;span id=&quot;cb5-8&quot;&gt;&lt;a href=&quot;#cb5-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  zipMatch _ _ &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Nothing&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now, I prefer the following style instead:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb6&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb6-1&quot;&gt;&lt;a href=&quot;#cb6-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;instance&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Unifiable&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;TypeF&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-2&quot;&gt;&lt;a href=&quot;#cb6-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  zipMatch a b &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-3&quot;&gt;&lt;a href=&quot;#cb6-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;kw&quot;&gt;case&lt;/span&gt; a &lt;span class=&quot;kw&quot;&gt;of&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-4&quot;&gt;&lt;a href=&quot;#cb6-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;dt&quot;&gt;BaseType&lt;/span&gt; a&amp;#39; &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-5&quot;&gt;&lt;a href=&quot;#cb6-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;        &lt;span class=&quot;dt&quot;&gt;BaseType&lt;/span&gt; b&amp;#39; &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;return&lt;/span&gt; b&lt;/span&gt;
&lt;span id=&quot;cb6-6&quot;&gt;&lt;a href=&quot;#cb6-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;        guard &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; a&amp;#39; &lt;span class=&quot;op&quot;&gt;==&lt;/span&gt; b&amp;#39;&lt;/span&gt;
&lt;span id=&quot;cb6-7&quot;&gt;&lt;a href=&quot;#cb6-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;        &lt;span class=&quot;fu&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;BaseType&lt;/span&gt; a&amp;#39;&lt;/span&gt;
&lt;span id=&quot;cb6-8&quot;&gt;&lt;a href=&quot;#cb6-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;dt&quot;&gt;Fun&lt;/span&gt; a1 a2 &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-9&quot;&gt;&lt;a href=&quot;#cb6-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;        &lt;span class=&quot;dt&quot;&gt;Fun&lt;/span&gt; b1 b2 &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;return&lt;/span&gt; b&lt;/span&gt;
&lt;span id=&quot;cb6-10&quot;&gt;&lt;a href=&quot;#cb6-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;        &lt;span class=&quot;fu&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Fun&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;Right&lt;/span&gt; (a1, b1)) (&lt;span class=&quot;dt&quot;&gt;Right&lt;/span&gt; (a2, b2))&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Why? First, &lt;a href=&quot;/articles/2014-05-09-clauses&quot;&gt;I really don’t
like multi-clause definitions&lt;/a&gt;. But the main reason is that the
second definition behaves more reliably when we add new constructors to
&lt;code&gt;TypeF&lt;/code&gt;. Namely, if we enable ghc warnings
(&lt;code&gt;-Wall&lt;/code&gt;) and extend &lt;code&gt;TypeF&lt;/code&gt; to include
tuples:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb7&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb7-1&quot;&gt;&lt;a href=&quot;#cb7-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;TypeF&lt;/span&gt; a &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;BaseType&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;String&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb7-2&quot;&gt;&lt;a href=&quot;#cb7-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;             &lt;span class=&quot;op&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Fun&lt;/span&gt; a a&lt;/span&gt;
&lt;span id=&quot;cb7-3&quot;&gt;&lt;a href=&quot;#cb7-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;             &lt;span class=&quot;op&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Tuple&lt;/span&gt; a a&lt;/span&gt;
&lt;span id=&quot;cb7-4&quot;&gt;&lt;a href=&quot;#cb7-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;deriving&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;Functor&lt;/span&gt;, &lt;span class=&quot;dt&quot;&gt;Foldable&lt;/span&gt;, &lt;span class=&quot;dt&quot;&gt;Traversable&lt;/span&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;… we’ll get a warning telling us not to forget to implement
&lt;code&gt;zipMatch&lt;/code&gt; for tuples:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;warning: [-Wincomplete-patterns]
    Pattern match(es) are non-exhaustive
    In a case alternative: Patterns not matched: (Tuple _ _)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If we went with the first version, however, we would get no warning,
because it contains a catch-all clause&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb9&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb9-1&quot;&gt;&lt;a href=&quot;#cb9-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  zipMatch _ _ &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Nothing&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;As a result, it is likely that we forget to update
&lt;code&gt;zipMatch&lt;/code&gt;, and our tuples will never unify.&lt;/p&gt;
&lt;p&gt;This is a common mistake people make when implementing binary
operations in Haskell, so I just wanted to point it out. But other than
that, both definitions are verbose and boilerplate-heavy.&lt;/p&gt;
&lt;p&gt;And it goes without saying that in real-life situations, the types we
want to unify tend to be bigger, and the boilerplate becomes even more
tedious.&lt;/p&gt;
&lt;p&gt;For instance, I’ve been working recently on implementing type
inference for the &lt;a href=&quot;http://docs.nstack.com/en/master/&quot;&gt;nstack&lt;/a&gt;
DSL, which includes tuples, records, sum types, optionals, arrays, the
void type, and many primitive types. Naturally, I wasn’t eager to write
&lt;code&gt;zipMatch&lt;/code&gt; by hand.&lt;/p&gt;
&lt;h2 id=&quot;generic-unifiable&quot;&gt;Generic Unifiable&lt;/h2&gt;
&lt;p&gt;Generic programming is a set of techniques to avoid writing
boilerplate such as our implementation of &lt;code&gt;zipMatch&lt;/code&gt;
above.&lt;/p&gt;
&lt;p&gt;Over the years, Haskell has acquired a lot of different generic
programming libraries.&lt;/p&gt;
&lt;p&gt;For most of my generic programming needs, I pick &lt;a
href=&quot;https://hackage.haskell.org/package/uniplate&quot;&gt;uniplate&lt;/a&gt;.
Uniplate is very simple to use and reasonably efficient. Occasionally I
have a problem that requires something more sophisticated, like &lt;a
href=&quot;https://hackage.haskell.org/package/generics-sop&quot;&gt;generics-sop&lt;/a&gt;
to &lt;a href=&quot;/articles/2015-07-26-better-yaml-parsing&quot;&gt;parse YAML&lt;/a&gt; or
&lt;a
href=&quot;https://hackage.haskell.org/package/traverse-with-class&quot;&gt;traverse-with-class&lt;/a&gt;
to &lt;a href=&quot;/articles/2013-03-04-open-name-resolution&quot;&gt;resolve names in
a Haskell AST&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;But none of these libraries can help us to implement a generic
&lt;code&gt;zipMatch&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Consider the following type:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb10&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb10-1&quot;&gt;&lt;a href=&quot;#cb10-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;TypeF&lt;/span&gt; a &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Foo&lt;/span&gt; a a&lt;/span&gt;
&lt;span id=&quot;cb10-2&quot;&gt;&lt;a href=&quot;#cb10-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;             &lt;span class=&quot;op&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Bar&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Int&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;String&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;A proper &lt;code&gt;zipMatch&lt;/code&gt; implementation works very differently
for &lt;code&gt;Foo&lt;/code&gt; and &lt;code&gt;Bar&lt;/code&gt;: &lt;code&gt;Foo&lt;/code&gt; has two
subterms to unify whereas &lt;code&gt;Bar&lt;/code&gt; has none.&lt;/p&gt;
&lt;p&gt;But most generics libraries don’t see this difference between
&lt;code&gt;Foo&lt;/code&gt; and &lt;code&gt;Bar&lt;/code&gt;. They don’t distinguish between
polymoprhic and non-polymorphic fields. Instead, they treat all fields
as non-polymorphic. From their point of view, &lt;code&gt;TypeF Bool&lt;/code&gt; is
exactly equivalent to&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb11&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb11-1&quot;&gt;&lt;a href=&quot;#cb11-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;TypeF&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Foo&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Bool&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Bool&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb11-2&quot;&gt;&lt;a href=&quot;#cb11-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;           &lt;span class=&quot;op&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Bar&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Int&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;String&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Luckily, there is a generic programming library that lets us “see”
type parameters. Well, just one type parameter, but that’s exactly
enough for &lt;code&gt;zipMatch&lt;/code&gt;. In other words, this library provides
a generic representation for type constructors of kind
&lt;code&gt;* -&amp;gt; *&lt;/code&gt;, whereas most other libraries only concern
themselves with ordinary types of kind &lt;code&gt;*&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;What is that library called? base.&lt;/p&gt;
&lt;p&gt;Seriously, starting from GHC 7.6 (released in 2012), the base library
includes a module &lt;code&gt;GHC.Generics&lt;/code&gt;. The module consists of:&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;&lt;p&gt;Several types (constants &lt;code&gt;K1&lt;/code&gt;, parameters
&lt;code&gt;Par1&lt;/code&gt;, sums &lt;code&gt;:+:&lt;/code&gt;, products &lt;code&gt;:*:&lt;/code&gt;,
compositions &lt;code&gt;:.:&lt;/code&gt;) out of which we can build different
algebraic types of kind &lt;code&gt;* -&amp;gt; *&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A class for representable algebraic data types,
&lt;code&gt;Generic1&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb12&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb12-1&quot;&gt;&lt;a href=&quot;#cb12-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Generic1&lt;/span&gt; f &lt;span class=&quot;kw&quot;&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb12-2&quot;&gt;&lt;a href=&quot;#cb12-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Rep1&lt;/span&gt;&lt;span class=&quot;ot&quot;&gt; f ::&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;*&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb12-3&quot;&gt;&lt;a href=&quot;#cb12-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;  from1  ::&lt;/span&gt; f a &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;Rep1&lt;/span&gt; f) a&lt;/span&gt;
&lt;span id=&quot;cb12-4&quot;&gt;&lt;a href=&quot;#cb12-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;  to1    ::&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;Rep1&lt;/span&gt; f) a &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; f a&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The associated type synonym &lt;code&gt;Rep1&lt;/code&gt; maps an algebraic data
type like &lt;code&gt;TypeF&lt;/code&gt; to an isomorphic type composed out of the
primitives like &lt;code&gt;K1&lt;/code&gt; and &lt;code&gt;:*:&lt;/code&gt;. The functions
&lt;code&gt;from1&lt;/code&gt; and &lt;code&gt;to1&lt;/code&gt; allow converting between the
two.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The compiler itself knows how to derive the &lt;code&gt;Generic1&lt;/code&gt;
instance for eligible types. Here is what it looks like:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb13&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb13-1&quot;&gt;&lt;a href=&quot;#cb13-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;{-# LANGUAGE DeriveFunctor, DeriveFoldable, DeriveTraversable #-}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb13-2&quot;&gt;&lt;a href=&quot;#cb13-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;{-# LANGUAGE DeriveGeneric #-}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb13-3&quot;&gt;&lt;a href=&quot;#cb13-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb13-4&quot;&gt;&lt;a href=&quot;#cb13-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;GHC.Generics&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;Generic1&lt;/span&gt;)&lt;/span&gt;
&lt;span id=&quot;cb13-5&quot;&gt;&lt;a href=&quot;#cb13-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb13-6&quot;&gt;&lt;a href=&quot;#cb13-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;TypeF&lt;/span&gt; a &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;BaseType&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;String&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb13-7&quot;&gt;&lt;a href=&quot;#cb13-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;             &lt;span class=&quot;op&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Fun&lt;/span&gt; a a&lt;/span&gt;
&lt;span id=&quot;cb13-8&quot;&gt;&lt;a href=&quot;#cb13-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;             &lt;span class=&quot;op&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Tuple&lt;/span&gt; a a&lt;/span&gt;
&lt;span id=&quot;cb13-9&quot;&gt;&lt;a href=&quot;#cb13-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;deriving&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;Functor&lt;/span&gt;, &lt;span class=&quot;dt&quot;&gt;Foldable&lt;/span&gt;, &lt;span class=&quot;dt&quot;&gt;Traversable&lt;/span&gt;, &lt;span class=&quot;dt&quot;&gt;Generic1&lt;/span&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;So, in order to have a generic &lt;code&gt;Unifiable&lt;/code&gt; instance, all I
had to do was:&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;Implement &lt;code&gt;Unifiable&lt;/code&gt; for the primitive types in
&lt;code&gt;GHC.Generics&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Add a default &lt;code&gt;zipMatch&lt;/code&gt; implementation to the
&lt;code&gt;Unifiable&lt;/code&gt; class.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;You can see the details in the &lt;a
href=&quot;https://github.com/wrengr/unification-fd/pull/4/files&quot;&gt;pull
request&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;complete-example&quot;&gt;Complete example&lt;/h2&gt;
&lt;p&gt;Here is a complete example that unifies &lt;code&gt;a -&amp;gt; (c, d)&lt;/code&gt;
with &lt;code&gt;c -&amp;gt; (a, b -&amp;gt; a)&lt;/code&gt;.&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb14&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb14-1&quot;&gt;&lt;a href=&quot;#cb14-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;{-# OPTIONS_GHC -Wall #-}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb14-2&quot;&gt;&lt;a href=&quot;#cb14-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;{-# LANGUAGE DeriveFunctor, DeriveFoldable,&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb14-3&quot;&gt;&lt;a href=&quot;#cb14-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;             DeriveTraversable, DeriveGeneric,&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb14-4&quot;&gt;&lt;a href=&quot;#cb14-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;             DeriveAnyClass, FlexibleContexts&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb14-5&quot;&gt;&lt;a href=&quot;#cb14-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;  #-}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb14-6&quot;&gt;&lt;a href=&quot;#cb14-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb14-7&quot;&gt;&lt;a href=&quot;#cb14-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Data.Functor.Identity&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb14-8&quot;&gt;&lt;a href=&quot;#cb14-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Control.Unification&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb14-9&quot;&gt;&lt;a href=&quot;#cb14-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Control.Unification.IntVar&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb14-10&quot;&gt;&lt;a href=&quot;#cb14-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Control.Unification.Types&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb14-11&quot;&gt;&lt;a href=&quot;#cb14-11&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Control.Monad.Trans.Except&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb14-12&quot;&gt;&lt;a href=&quot;#cb14-12&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Control.Monad.Trans.Class&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb14-13&quot;&gt;&lt;a href=&quot;#cb14-13&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;qualified&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Data.Map&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Map&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb14-14&quot;&gt;&lt;a href=&quot;#cb14-14&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;GHC.Generics&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb14-15&quot;&gt;&lt;a href=&quot;#cb14-15&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb14-16&quot;&gt;&lt;a href=&quot;#cb14-16&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;TypeF&lt;/span&gt; a &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;BaseType&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;String&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb14-17&quot;&gt;&lt;a href=&quot;#cb14-17&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;             &lt;span class=&quot;op&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Fun&lt;/span&gt; a a&lt;/span&gt;
&lt;span id=&quot;cb14-18&quot;&gt;&lt;a href=&quot;#cb14-18&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;             &lt;span class=&quot;op&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Tuple&lt;/span&gt; a a&lt;/span&gt;
&lt;span id=&quot;cb14-19&quot;&gt;&lt;a href=&quot;#cb14-19&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;deriving&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;Functor&lt;/span&gt;, &lt;span class=&quot;dt&quot;&gt;Foldable&lt;/span&gt;, &lt;span class=&quot;dt&quot;&gt;Traversable&lt;/span&gt;, &lt;span class=&quot;dt&quot;&gt;Show&lt;/span&gt;, &lt;span class=&quot;dt&quot;&gt;Generic1&lt;/span&gt;, &lt;span class=&quot;dt&quot;&gt;Unifiable&lt;/span&gt;)&lt;/span&gt;
&lt;span id=&quot;cb14-20&quot;&gt;&lt;a href=&quot;#cb14-20&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;co&quot;&gt;--                                              ^^^^^^^^^^^^^^^^^^^&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb14-21&quot;&gt;&lt;a href=&quot;#cb14-21&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;co&quot;&gt;--                                           the magic happens here&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb14-22&quot;&gt;&lt;a href=&quot;#cb14-22&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb14-23&quot;&gt;&lt;a href=&quot;#cb14-23&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;unified ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;IntBindingT&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;TypeF&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Identity&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb14-24&quot;&gt;&lt;a href=&quot;#cb14-24&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  (&lt;span class=&quot;dt&quot;&gt;Either&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb14-25&quot;&gt;&lt;a href=&quot;#cb14-25&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    (&lt;span class=&quot;dt&quot;&gt;UFailure&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;TypeF&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;IntVar&lt;/span&gt;)&lt;/span&gt;
&lt;span id=&quot;cb14-26&quot;&gt;&lt;a href=&quot;#cb14-26&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    (&lt;span class=&quot;dt&quot;&gt;UTerm&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;TypeF&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;String&lt;/span&gt;))&lt;/span&gt;
&lt;span id=&quot;cb14-27&quot;&gt;&lt;a href=&quot;#cb14-27&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;unified &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; runExceptT &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb14-28&quot;&gt;&lt;a href=&quot;#cb14-28&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  a_var &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; lift freeVar&lt;/span&gt;
&lt;span id=&quot;cb14-29&quot;&gt;&lt;a href=&quot;#cb14-29&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  b_var &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; lift freeVar&lt;/span&gt;
&lt;span id=&quot;cb14-30&quot;&gt;&lt;a href=&quot;#cb14-30&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  c_var &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; lift freeVar&lt;/span&gt;
&lt;span id=&quot;cb14-31&quot;&gt;&lt;a href=&quot;#cb14-31&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  d_var &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; lift freeVar&lt;/span&gt;
&lt;span id=&quot;cb14-32&quot;&gt;&lt;a href=&quot;#cb14-32&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;let&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb14-33&quot;&gt;&lt;a href=&quot;#cb14-33&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    a &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;UVar&lt;/span&gt; a_var&lt;/span&gt;
&lt;span id=&quot;cb14-34&quot;&gt;&lt;a href=&quot;#cb14-34&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    b &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;UVar&lt;/span&gt; b_var&lt;/span&gt;
&lt;span id=&quot;cb14-35&quot;&gt;&lt;a href=&quot;#cb14-35&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    c &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;UVar&lt;/span&gt; c_var&lt;/span&gt;
&lt;span id=&quot;cb14-36&quot;&gt;&lt;a href=&quot;#cb14-36&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    d &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;UVar&lt;/span&gt; d_var&lt;/span&gt;
&lt;span id=&quot;cb14-37&quot;&gt;&lt;a href=&quot;#cb14-37&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;/span&gt;
&lt;span id=&quot;cb14-38&quot;&gt;&lt;a href=&quot;#cb14-38&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    term1 &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;UTerm&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;Fun&lt;/span&gt; a (&lt;span class=&quot;dt&quot;&gt;UTerm&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Tuple&lt;/span&gt; c d))&lt;/span&gt;
&lt;span id=&quot;cb14-39&quot;&gt;&lt;a href=&quot;#cb14-39&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    term2 &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;UTerm&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;Fun&lt;/span&gt; c (&lt;span class=&quot;dt&quot;&gt;UTerm&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Tuple&lt;/span&gt; a (&lt;span class=&quot;dt&quot;&gt;UTerm&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Fun&lt;/span&gt; b a)))&lt;/span&gt;
&lt;span id=&quot;cb14-40&quot;&gt;&lt;a href=&quot;#cb14-40&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb14-41&quot;&gt;&lt;a href=&quot;#cb14-41&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  result &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; applyBindings &lt;span class=&quot;op&quot;&gt;=&amp;lt;&amp;lt;&lt;/span&gt; unify term1 term2&lt;/span&gt;
&lt;span id=&quot;cb14-42&quot;&gt;&lt;a href=&quot;#cb14-42&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb14-43&quot;&gt;&lt;a href=&quot;#cb14-43&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;co&quot;&gt;-- replace integer variable identifiers with variable names&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb14-44&quot;&gt;&lt;a href=&quot;#cb14-44&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;let&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb14-45&quot;&gt;&lt;a href=&quot;#cb14-45&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    all_vars &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; Map.fromList&lt;/span&gt;
&lt;span id=&quot;cb14-46&quot;&gt;&lt;a href=&quot;#cb14-46&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      [(getVarID a_var, &lt;span class=&quot;st&quot;&gt;&amp;quot;a&amp;quot;&lt;/span&gt;)&lt;/span&gt;
&lt;span id=&quot;cb14-47&quot;&gt;&lt;a href=&quot;#cb14-47&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      ,(getVarID b_var, &lt;span class=&quot;st&quot;&gt;&amp;quot;b&amp;quot;&lt;/span&gt;)&lt;/span&gt;
&lt;span id=&quot;cb14-48&quot;&gt;&lt;a href=&quot;#cb14-48&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      ,(getVarID c_var, &lt;span class=&quot;st&quot;&gt;&amp;quot;c&amp;quot;&lt;/span&gt;)&lt;/span&gt;
&lt;span id=&quot;cb14-49&quot;&gt;&lt;a href=&quot;#cb14-49&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      ,(getVarID d_var, &lt;span class=&quot;st&quot;&gt;&amp;quot;d&amp;quot;&lt;/span&gt;)&lt;/span&gt;
&lt;span id=&quot;cb14-50&quot;&gt;&lt;a href=&quot;#cb14-50&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      ]&lt;/span&gt;
&lt;span id=&quot;cb14-51&quot;&gt;&lt;a href=&quot;#cb14-51&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb14-52&quot;&gt;&lt;a href=&quot;#cb14-52&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;fu&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;fmap&lt;/span&gt; ((all_vars &lt;span class=&quot;op&quot;&gt;Map.!&lt;/span&gt;) &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt; getVarID) result&lt;/span&gt;
&lt;span id=&quot;cb14-53&quot;&gt;&lt;a href=&quot;#cb14-53&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb14-54&quot;&gt;&lt;a href=&quot;#cb14-54&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;main ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;IO&lt;/span&gt; ()&lt;/span&gt;
&lt;span id=&quot;cb14-55&quot;&gt;&lt;a href=&quot;#cb14-55&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;main &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt; runIdentity &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; evalIntBindingT unified&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Output:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Right (Fun &amp;quot;c&amp;quot; (Tuple &amp;quot;c&amp;quot; (Fun &amp;quot;b&amp;quot; &amp;quot;c&amp;quot;)))&lt;/code&gt;&lt;/pre&gt;
</description>
                        <pubDate>Sat, 17 Jun 2017 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2017-06-17-generic-unification</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2017-06-17-generic-unification.html</guid>
                </item>
        
                <item>
                        <title>On friendly contributing policies</title>
                        <description>&lt;p&gt;&lt;a href=&quot;http://ndmitchell.com/&quot;&gt;Neil Mitchell&lt;/a&gt; gave a talk at &lt;a
href=&quot;https://zurihac.info/&quot;&gt;ZuriHac&lt;/a&gt; about drive-by contributions. I
did not attend ZuriHac this year, but Neil published the &lt;a
href=&quot;http://ndmitchell.com/downloads/slides-drive-by_haskell_contributions-09_jun_2017.pdf&quot;&gt;slides&lt;/a&gt;
of his talk. While I was skimming through them, one caught my
attention:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/img/drive-by.png&quot; /&gt;&lt;/p&gt;
&lt;p&gt;The quote on the bottom-right is taken from the &lt;a
href=&quot;https://github.com/haskell-suite/haskell-src-exts/blob/1a1368a3e7f6e054fb9d9310348d4fdfbc148071/CONTRIBUTING.md#bug-fix-or-new-extension&quot;&gt;haskell-src-exts
contributing policy&lt;/a&gt;, which I wrote back when I &lt;a
href=&quot;/articles/2014-11-01-rebalancing-open-source-portfolio&quot;&gt;was&lt;/a&gt;
its maintainer.&lt;/p&gt;
&lt;p&gt;As I said, I didn’t have the chance to attend the talk, and the video
does not seem to be released yet, so I can only guess the message of
this slide (perhaps Neil or someone who was present will clarify) — but
it looks to me that this quote is an example of an unfriendly message
that is contrasted to the first, welcoming, message.&lt;/p&gt;
&lt;p&gt;If that’s the case, this doesn’t seem fair to me: the quote is
cherry-picked from a section that starts with&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;So, you’ve fixed a bug or implemented an extension. Awesome!&lt;/p&gt;
&lt;p&gt;We strive to get every such pull request reviewed and merged within a
month.&lt;/p&gt;
&lt;p&gt;For best results, please follow these guidelines:&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;You could argue whether this is friendly enough or not, but you have
to admit that it is at least considerate of contributors’ time and
interests.&lt;/p&gt;
&lt;p&gt;But what about those two particular sentences on the slide? Are they
rude? Is it because they don’t have “please” in them?&lt;/p&gt;
&lt;p&gt;I guess that, taken in isolation, they do seem rude for that reason,
but they are part of a list of instructions, and you can make a list of
instructions only so much polite. In particular, I don’t think that
simply adding “please” in front of every imperative would make it any
nicer — but I am not a native English speaker and could be wrong.&lt;/p&gt;
&lt;p&gt;On the other hand, if I wrote that policy as a list of polite
requests (“Could you please not put multiple unrelated changes in a
single pull request?”), I feel that it would take more time and effort
for a potential contributor to comprehend and extract the essence of
what’s written. That would be disrespectful to the contributor’s time.
Besides, if you have 10+ polite requests in a row, it starts to look as
a caricature.&lt;/p&gt;
&lt;p&gt;That said, I am open to constructive criticism. If you have ideas
about how I could have written it better, please drop me a line.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Update.&lt;/em&gt; Neil has written a &lt;a
href=&quot;https://gist.github.com/ndmitchell/e64ea9a85d24d4d53ab3b2b1b87b6c5d&quot;&gt;nice
detailed response&lt;/a&gt;, which I greatly appreciate.&lt;/p&gt;
</description>
                        <pubDate>Mon, 12 Jun 2017 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2017-06-12-friendly-contributing-policies</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2017-06-12-friendly-contributing-policies.html</guid>
                </item>
        
                <item>
                        <title>Word vs. Int</title>
                        <description>&lt;p&gt;When dealing with bounded non-negative integer quantities in Haskell,
should we use &lt;code&gt;Word&lt;/code&gt; or &lt;code&gt;Int&lt;/code&gt; to represent
them?&lt;/p&gt;
&lt;p&gt;Some argue that we shoud use &lt;code&gt;Word&lt;/code&gt; because then we
automatically know that our quantities are non-negative.&lt;/p&gt;
&lt;blockquote class=&quot;twitter-tweet&quot; data-lang=&quot;en&quot;&gt;
&lt;p lang=&quot;en&quot; dir=&quot;ltr&quot;&gt;
because there&apos;s many things that shouldn&apos;t be negative by semantic.
there&apos;s no such as -5 coins in your wallet, or a body weight being -1kg.
&lt;/p&gt;
— Vincent Hanquez (&lt;span class=&quot;citation&quot;
data-cites=&quot;vincenthz&quot;&gt;@vincenthz&lt;/span&gt;)
&lt;a href=&quot;https://twitter.com/vincenthz/status/871627597570068484&quot;&gt;June
5, 2017&lt;/a&gt;
&lt;/blockquote&gt;
&lt;p&gt;There is a famous in typed functional programming circles maxim that
says “make illegal states unrepresentable”. Following this maxim
generally leads to code that is more likely correct, but in each
specific instance we should check that we are indeed getting closer to
our goal (writing correct code) instead of following a cargo cult.&lt;/p&gt;
&lt;p&gt;So let’s examine whether avoiding unrepresentable negative states
serves us well here.&lt;/p&gt;
&lt;p&gt;If our program is correct and never arrives at a negative result, it
does not matter whether we use &lt;code&gt;Int&lt;/code&gt; or &lt;code&gt;Word&lt;/code&gt;.
(I’m setting overflow issues aside for now.)&lt;/p&gt;
&lt;p&gt;Thus, we only need to consider a case when we subtract a bigger
number from a smaller number because of a logic flaw in our program.&lt;/p&gt;
&lt;p&gt;Here is what happens depending on what type we use:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb1&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb1-1&quot;&gt;&lt;a href=&quot;#cb1-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;op&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;ot&quot;&gt; ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Int&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-2&quot;&gt;&lt;a href=&quot;#cb1-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;op&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-3&quot;&gt;&lt;a href=&quot;#cb1-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;op&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;ot&quot;&gt; ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Word&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-4&quot;&gt;&lt;a href=&quot;#cb1-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;dv&quot;&gt;18446744073709551615&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Which answer would you prefer?&lt;/p&gt;
&lt;p&gt;Even though technically &lt;code&gt;-1&lt;/code&gt; doesn’t satisfy our
constraints and &lt;code&gt;18446744073709551615&lt;/code&gt; does, I would choose
&lt;code&gt;-1&lt;/code&gt; over &lt;code&gt;18446744073709551615&lt;/code&gt; any day, for two
reasons:&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;&lt;p&gt;There is a chance that some downstream computation will recognize
a negative number and report an error.&lt;/p&gt;
&lt;p&gt;A stock exchange won’t let me buy -1 shares, and the engine won’t let
me set the speed to &lt;code&gt;-1&lt;/code&gt; km/h. (These are terrible examples,
I know, but hopefully they illustrate my point.)&lt;/p&gt;
&lt;p&gt;Will those systems also reject &lt;code&gt;18446744073709551615&lt;/code&gt;
shares or km/h? If they are well designed, yes, but I’d rather not test
this in production.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;For a human, it is easier to notice the mistake if the answer
does not make any sense at all than if the answer kinda makes sense.&lt;/p&gt;
&lt;p&gt;If an experienced programmer sees an unexpectedly huge number like
&lt;code&gt;18446744073709551615&lt;/code&gt;, she will easily connect it to an
underflow, although it’s an extra logical step she has to make. A less
experienced programmer might spend quite a bit of time figuring this
out.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;In any case, I don’t see any advantage of replacing an invalid number
such as &lt;code&gt;-1&lt;/code&gt; with a technically-valid-but-meaningless number
like &lt;code&gt;18446744073709551615&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Ben Millwood &lt;a
href=&quot;https://mail.haskell.org/pipermail/libraries/2014-August/023549.html&quot;&gt;said
it well&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I moreover feel like, e.g. &lt;code&gt;length :: [a] -&amp;gt; Word&lt;/code&gt; (or
things of that ilk) would be even more of a mistake, because type
inference will spread that &lt;code&gt;Word&lt;/code&gt; everywhere, and
&lt;code&gt;2 - 3 :: Word&lt;/code&gt; is catastrophically wrong. Although it seems
nice to have an output type for non-negative functions that only has
non-negative values, in fact Word happily supports subtraction,
conversion from Integer, even negation (!) without a hint that anything
has gone amiss. So I just don’t believe that it is a type suitable for
general “positive integer” applications.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Moritz Kiefer makes &lt;a
href=&quot;https://twitter.com/cocreature/status/968530466499383296&quot;&gt;another
great point&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;One problem that I’ve run into quite a few times with Word is
&lt;code&gt;[0 .. n - 1]&lt;/code&gt; which is quite common if you’re mapping over
array indices. That alone has mostly resulted in me being really careful
when I use Word.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Here Moritz is referring to the fact that the expression
&lt;code&gt;[0 .. n-1] :: [Word]&lt;/code&gt; results in the list of all integers
&lt;code&gt;0 &amp;lt;= i &amp;lt; n&lt;/code&gt; unless &lt;code&gt;n&lt;/code&gt; is 0, in which case
&lt;code&gt;n-1&lt;/code&gt; wraps to &lt;code&gt;maxBound&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&quot;natural&quot;&gt;Natural&lt;/h2&gt;
&lt;p&gt;There is a way to get the best of both worlds, though: the
&lt;code&gt;Natural&lt;/code&gt; type from &lt;code&gt;Numeric.Natural&lt;/code&gt;.&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;&lt;p&gt;It is an arbitrary-precision integer, so we don’t have to worry
about overflow.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;It is a non-negative type, so the invalid state is not
representable.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;It raises an exception upon underflow, making the errors in the
code prominent:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb2&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb2-1&quot;&gt;&lt;a href=&quot;#cb2-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;op&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;ot&quot;&gt; ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Natural&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-2&quot;&gt;&lt;a href=&quot;#cb2-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;op&quot;&gt;***&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Exception&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; arithmetic underflow&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;There are perhaps a couple of valid use cases for &lt;code&gt;Word&lt;/code&gt;
that I can think of, but they are fairly exotic. (I am not talking here
about the types such as &lt;code&gt;Word32&lt;/code&gt; or &lt;code&gt;Word64&lt;/code&gt;,
which are indespensible for bit manipulation.) Most of the time we
should prefer either &lt;code&gt;Int&lt;/code&gt; or &lt;code&gt;Natural&lt;/code&gt; to
&lt;code&gt;Word&lt;/code&gt;.&lt;/p&gt;
</description>
                        <pubDate>Mon, 05 Jun 2017 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2017-06-05-word-vs-int</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2017-06-05-word-vs-int.html</guid>
                </item>
        
                <item>
                        <title>Universally stateless monads</title>
                        <description>&lt;h2 id=&quot;background-monad-control-and-stateless-monads&quot;&gt;Background:
monad-control and stateless monads&lt;/h2&gt;
&lt;p&gt;The &lt;a
href=&quot;https://hackage.haskell.org/package/monad-control&quot;&gt;monad-control&lt;/a&gt;
package allows to lift IO functions such as&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb1&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb1-1&quot;&gt;&lt;a href=&quot;#cb1-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;forkIO ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;IO&lt;/span&gt; () &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;IO&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;ThreadId&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-2&quot;&gt;&lt;a href=&quot;#cb1-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-3&quot;&gt;&lt;a href=&quot;#cb1-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;fu&quot;&gt;catch&lt;/span&gt;&lt;span class=&quot;ot&quot;&gt; ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Exception&lt;/span&gt; e &lt;span class=&quot;ot&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;IO&lt;/span&gt; a &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; (e &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;IO&lt;/span&gt; a) &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;IO&lt;/span&gt; a&lt;/span&gt;
&lt;span id=&quot;cb1-4&quot;&gt;&lt;a href=&quot;#cb1-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-5&quot;&gt;&lt;a href=&quot;#cb1-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;allocate ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;MonadResource&lt;/span&gt; m &lt;span class=&quot;ot&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;IO&lt;/span&gt; a &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; (a &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;IO&lt;/span&gt; ()) &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; m (&lt;span class=&quot;dt&quot;&gt;ReleaseKey&lt;/span&gt;, a)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;to IO-based monad stacks such as
&lt;code&gt;StateT Int (ReaderT Bool IO)&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The core idea of the package is the associated type &lt;code&gt;StM&lt;/code&gt;,
which, for a given monad &lt;code&gt;m&lt;/code&gt; and result type &lt;code&gt;a&lt;/code&gt;,
calculates the “state” of &lt;code&gt;m&lt;/code&gt; at &lt;code&gt;a&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The “state” of a monad is whatever the “run” function for this monad
returns.&lt;/p&gt;
&lt;p&gt;For instance, for &lt;code&gt;StateT Int IO Char&lt;/code&gt;, we have&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb2&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb2-1&quot;&gt;&lt;a href=&quot;#cb2-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;runStateT ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;StateT&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Int&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;IO&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Char&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Int&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;IO&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;Char&lt;/span&gt;, &lt;span class=&quot;dt&quot;&gt;Int&lt;/span&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The result type of this function (minus the outer monad constructor,
&lt;code&gt;IO&lt;/code&gt;, which is always there) is &lt;code&gt;(Char, Int)&lt;/code&gt;, and
that is what &lt;code&gt;StM (StateT Int IO) Char&lt;/code&gt; should expand to:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb3&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb3-1&quot;&gt;&lt;a href=&quot;#cb3-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;op&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;:&lt;/span&gt;kind&lt;span class=&quot;op&quot;&gt;!&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;StM&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;StateT&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Int&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;IO&lt;/span&gt;) &lt;span class=&quot;dt&quot;&gt;Char&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-2&quot;&gt;&lt;a href=&quot;#cb3-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;dt&quot;&gt;StM&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;StateT&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Int&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;IO&lt;/span&gt;) &lt;span class=&quot;dt&quot;&gt;Char&lt;/span&gt;&lt;span class=&quot;ot&quot;&gt; ::&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;*&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-3&quot;&gt;&lt;a href=&quot;#cb3-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;Char&lt;/span&gt;, &lt;span class=&quot;dt&quot;&gt;Int&lt;/span&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;In this case, &lt;code&gt;StM m a&lt;/code&gt; is not the same as &lt;code&gt;a&lt;/code&gt;;
it contains &lt;code&gt;a&lt;/code&gt; plus some extra information.&lt;/p&gt;
&lt;p&gt;In other cases, &lt;code&gt;StM m a&lt;/code&gt; may not contain an
&lt;code&gt;a&lt;/code&gt; at all; for instance&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb4&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb4-1&quot;&gt;&lt;a href=&quot;#cb4-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;op&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;:&lt;/span&gt;kind&lt;span class=&quot;op&quot;&gt;!&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;StM&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;ExceptT&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Text&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;IO&lt;/span&gt;) &lt;span class=&quot;dt&quot;&gt;Char&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-2&quot;&gt;&lt;a href=&quot;#cb4-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;dt&quot;&gt;StM&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;ExceptT&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Text&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;IO&lt;/span&gt;) &lt;span class=&quot;dt&quot;&gt;Char&lt;/span&gt;&lt;span class=&quot;ot&quot;&gt; ::&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;*&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-3&quot;&gt;&lt;a href=&quot;#cb4-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Either&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Text&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Char&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;and we cannot always extract a &lt;code&gt;Char&lt;/code&gt; from
&lt;code&gt;Either Text Char&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;For some monads, though, &lt;code&gt;StM m a&lt;/code&gt; reduces precisely to
&lt;code&gt;a&lt;/code&gt;. I call such monads “stateless”. A notable example is the
reader monad:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb5&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb5-1&quot;&gt;&lt;a href=&quot;#cb5-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;op&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;:&lt;/span&gt;kind&lt;span class=&quot;op&quot;&gt;!&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;StM&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;ReaderT&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Int&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;IO&lt;/span&gt;) &lt;span class=&quot;dt&quot;&gt;Bool&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-2&quot;&gt;&lt;a href=&quot;#cb5-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;dt&quot;&gt;StM&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;ReaderT&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Int&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;IO&lt;/span&gt;) &lt;span class=&quot;dt&quot;&gt;Bool&lt;/span&gt;&lt;span class=&quot;ot&quot;&gt; ::&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;*&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-3&quot;&gt;&lt;a href=&quot;#cb5-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Bool&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Definition.&lt;/strong&gt; A monad &lt;code&gt;m&lt;/code&gt; is stateless at
type &lt;code&gt;a&lt;/code&gt; iff &lt;code&gt;StM m a ~ a&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Note that a monad like &lt;code&gt;ReaderT (IORef Int) IO&lt;/code&gt; is also
stateless, even though one can use it to implement stateful
programs.&lt;/p&gt;
&lt;p&gt;The important feature of stateless monads is that we can fork them
without duplicating the state and terminate them without losing the
state. The monad-control package works best with stateless monads: it is
&lt;a
href=&quot;http://blog.ezyang.com/2012/01/monadbasecontrol-is-unsound/&quot;&gt;less
tricky&lt;/a&gt; to understand, and you can do &lt;a
href=&quot;/articles/2014-12-26-monad-control-type-synonyms&quot;&gt;some things&lt;/a&gt;
with stateless monads that are hard or impossible to do with arbitrary
&lt;code&gt;MonadBaseControl&lt;/code&gt; monads.&lt;/p&gt;
&lt;h2 id=&quot;universally-stateless-monads&quot;&gt;Universally stateless monads&lt;/h2&gt;
&lt;p&gt;When both the monad &lt;code&gt;m&lt;/code&gt; and the result type &lt;code&gt;a&lt;/code&gt;
are known, the compiler can expand the associated synonym
&lt;code&gt;StM m a&lt;/code&gt; and decide whether &lt;code&gt;StM m a ~ a&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;However, &lt;a href=&quot;/articles/2014-06-11-problem-with-mtl&quot;&gt;there are
good reasons&lt;/a&gt; to keep the monad &lt;code&gt;m&lt;/code&gt; polymorphic and
instead impose the constraints (e.g. &lt;code&gt;MonadReader Int m&lt;/code&gt;)
that &lt;code&gt;m&lt;/code&gt; must satisfy.&lt;/p&gt;
&lt;p&gt;In this case, the compiler cannot know &lt;em&gt;a priori&lt;/em&gt; that
&lt;code&gt;m&lt;/code&gt; is stateless, and we need to explicitly state that in the
function signature. In &lt;a
href=&quot;/articles/2014-12-26-monad-control-type-synonyms&quot;&gt;Taking advantage
of type synonyms in monad-control&lt;/a&gt;, I showed one such example:
running a web application with access to the database. In order to
convince the compiler that &lt;code&gt;m&lt;/code&gt; is stateless, I needed to add
the constraint&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb6&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb6-1&quot;&gt;&lt;a href=&quot;#cb6-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;dt&quot;&gt;StM&lt;/span&gt; m &lt;span class=&quot;dt&quot;&gt;ResponseReceived&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;~&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;ResponseReceived&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;to the type signature.&lt;/p&gt;
&lt;p&gt;As you can see, this doesn’t quite say “monad &lt;code&gt;m&lt;/code&gt; is
stateless”; instead it says “monad &lt;code&gt;m&lt;/code&gt; is stateless at type
&lt;code&gt;a&lt;/code&gt;” (where &lt;code&gt;a&lt;/code&gt; is &lt;code&gt;ResponseReceived&lt;/code&gt;
in the above example).&lt;/p&gt;
&lt;p&gt;This is fine if we only use monad-control at one result type. But if
we use monad-control functions at many different types, the number of
constraints required quickly gets out of hand.&lt;/p&gt;
&lt;p&gt;As an example, consider the &lt;code&gt;allocate&lt;/code&gt; function from &lt;a
href=&quot;https://hackage.haskell.org/package/resourcet&quot;&gt;resourcet&lt;/a&gt;’s
&lt;code&gt;Control.Monad.Trans.Resource&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb7&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb7-1&quot;&gt;&lt;a href=&quot;#cb7-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;allocate ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;MonadResource&lt;/span&gt; m &lt;span class=&quot;ot&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;IO&lt;/span&gt; a &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; (a &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;IO&lt;/span&gt; ()) &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; m (&lt;span class=&quot;dt&quot;&gt;ReleaseKey&lt;/span&gt;, a)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;As the module’s documentation says,&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;One point to note: all register cleanup actions live in the IO monad,
not the main monad. This allows both more efficient code, and for monads
to be transformed.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;In practice, it is often useful for the register and cleanup actions
to live in the main monad. monad-control lets us lift the
&lt;code&gt;allocate&lt;/code&gt; function:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb8&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb8-1&quot;&gt;&lt;a href=&quot;#cb8-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;{-# LANGUAGE FlexibleContexts, TypeFamilies, ScopedTypeVariables #-}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb8-2&quot;&gt;&lt;a href=&quot;#cb8-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Control.Monad.Trans.Control&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb8-3&quot;&gt;&lt;a href=&quot;#cb8-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Control.Monad.Trans.Resource&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb8-4&quot;&gt;&lt;a href=&quot;#cb8-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb8-5&quot;&gt;&lt;a href=&quot;#cb8-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;allocateM&lt;/span&gt;
&lt;span id=&quot;cb8-6&quot;&gt;&lt;a href=&quot;#cb8-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;  ::&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;forall&lt;/span&gt; m a &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;MonadBaseControl&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;IO&lt;/span&gt; m, &lt;span class=&quot;dt&quot;&gt;MonadResource&lt;/span&gt; m,&lt;/span&gt;
&lt;span id=&quot;cb8-7&quot;&gt;&lt;a href=&quot;#cb8-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;                   &lt;span class=&quot;dt&quot;&gt;StM&lt;/span&gt; m a &lt;span class=&quot;op&quot;&gt;~&lt;/span&gt; a, &lt;span class=&quot;dt&quot;&gt;StM&lt;/span&gt; m () &lt;span class=&quot;op&quot;&gt;~&lt;/span&gt; (), &lt;span class=&quot;dt&quot;&gt;StM&lt;/span&gt; m (&lt;span class=&quot;dt&quot;&gt;ReleaseKey&lt;/span&gt;, a) &lt;span class=&quot;op&quot;&gt;~&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;ReleaseKey&lt;/span&gt;, a))&lt;/span&gt;
&lt;span id=&quot;cb8-8&quot;&gt;&lt;a href=&quot;#cb8-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;ot&quot;&gt;=&amp;gt;&lt;/span&gt; m a &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; (a &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; m ()) &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; m (&lt;span class=&quot;dt&quot;&gt;ReleaseKey&lt;/span&gt;, a)&lt;/span&gt;
&lt;span id=&quot;cb8-9&quot;&gt;&lt;a href=&quot;#cb8-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;allocateM acquire release &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb8-10&quot;&gt;&lt;a href=&quot;#cb8-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  liftBaseWith&lt;/span&gt;
&lt;span id=&quot;cb8-11&quot;&gt;&lt;a href=&quot;#cb8-11&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    (\runInIO &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; runInIO &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; allocate&lt;/span&gt;
&lt;span id=&quot;cb8-12&quot;&gt;&lt;a href=&quot;#cb8-12&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      (runInIO acquire)&lt;/span&gt;
&lt;span id=&quot;cb8-13&quot;&gt;&lt;a href=&quot;#cb8-13&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      (runInIO &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt; release))&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This small function requires three different stateless constraints —
constraints of the form &lt;code&gt;StM m x ~ x&lt;/code&gt; — and two additional
stateless constraints per each additional type &lt;code&gt;a&lt;/code&gt; at which
we use it.&lt;/p&gt;
&lt;p&gt;These constraints are artefacts of the way type synonyms work in
Haskell; &lt;code&gt;StM m a&lt;/code&gt; is not really supposed to depend on
&lt;code&gt;a&lt;/code&gt;. If a monad is stateless, it is (pretty much always)
stateless at every result type.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Definition.&lt;/strong&gt; A monad &lt;code&gt;m&lt;/code&gt; is universally
stateless iff for all &lt;code&gt;a&lt;/code&gt;, &lt;code&gt;StM m a ~ a&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;In order to capture this universal statelessness in a single
constraint, we can use &lt;code&gt;Forall&lt;/code&gt; from the &lt;a
href=&quot;https://hackage.haskell.org/package/constraints&quot;&gt;constraints&lt;/a&gt;
package.&lt;/p&gt;
&lt;p&gt;First, we need to transform the constraint &lt;code&gt;StM m a ~ a&lt;/code&gt;
to a form in which it can be partially applied, as we want to abstract
over &lt;code&gt;a&lt;/code&gt;. Simply saying&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb9&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb9-1&quot;&gt;&lt;a href=&quot;#cb9-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;StatelessAt&lt;/span&gt; m a &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;StM&lt;/span&gt; m a &lt;span class=&quot;op&quot;&gt;~&lt;/span&gt; a&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;won’t do because type synonyms need to be fully applied:
&lt;code&gt;StatelessAt m&lt;/code&gt; is not a valid type.&lt;/p&gt;
&lt;p&gt;We need to use a trick to create a class synonym:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb10&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb10-1&quot;&gt;&lt;a href=&quot;#cb10-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;class&lt;/span&gt;    &lt;span class=&quot;dt&quot;&gt;StM&lt;/span&gt; m a &lt;span class=&quot;op&quot;&gt;~&lt;/span&gt; a &lt;span class=&quot;ot&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;StatelessAt&lt;/span&gt; m a&lt;/span&gt;
&lt;span id=&quot;cb10-2&quot;&gt;&lt;a href=&quot;#cb10-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;instance&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;StM&lt;/span&gt; m a &lt;span class=&quot;op&quot;&gt;~&lt;/span&gt; a &lt;span class=&quot;ot&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;StatelessAt&lt;/span&gt; m a&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now &lt;code&gt;StatelessAt&lt;/code&gt; is a legitimate class constraint (not a
type synonym), and so we can abstract over its second argument with
&lt;code&gt;Forall&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb11&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb11-1&quot;&gt;&lt;a href=&quot;#cb11-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Stateless&lt;/span&gt; m &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Forall&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;StatelessAt&lt;/span&gt; m)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now we only need to include the &lt;code&gt;Stateless m&lt;/code&gt; constraint,
and every time we need to prove that &lt;code&gt;StM m a ~ a&lt;/code&gt; for some
result type &lt;code&gt;a&lt;/code&gt;, we wrap the monadic computation in
&lt;code&gt;assertStateless @a (...)&lt;/code&gt;, where
&lt;code&gt;assertStateless&lt;/code&gt; is defined as follows:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb12&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb12-1&quot;&gt;&lt;a href=&quot;#cb12-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;assertStateless ::&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;forall&lt;/span&gt; a m b &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Stateless&lt;/span&gt; m &lt;span class=&quot;ot&quot;&gt;=&amp;gt;&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;StM&lt;/span&gt; m a &lt;span class=&quot;op&quot;&gt;~&lt;/span&gt; a &lt;span class=&quot;ot&quot;&gt;=&amp;gt;&lt;/span&gt; m b) &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; m b&lt;/span&gt;
&lt;span id=&quot;cb12-2&quot;&gt;&lt;a href=&quot;#cb12-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;assertStateless action &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; action \\ (&lt;span class=&quot;ot&quot;&gt;inst ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Stateless&lt;/span&gt; m &lt;span class=&quot;op&quot;&gt;:-&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;StatelessAt&lt;/span&gt; m a)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The type signature of &lt;code&gt;assertStateless&lt;/code&gt; is crafted in such
a way that we only need to specify &lt;code&gt;a&lt;/code&gt;, and &lt;code&gt;m&lt;/code&gt; is
inferred to be the “current” monad. We could have given
&lt;code&gt;assertStateless&lt;/code&gt; a more general type&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb13&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb13-1&quot;&gt;&lt;a href=&quot;#cb13-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;assertStateless ::&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;forall&lt;/span&gt; m a r &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Stateless&lt;/span&gt; m &lt;span class=&quot;ot&quot;&gt;=&amp;gt;&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;StM&lt;/span&gt; m a &lt;span class=&quot;op&quot;&gt;~&lt;/span&gt; a &lt;span class=&quot;ot&quot;&gt;=&amp;gt;&lt;/span&gt; r) &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; r&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;but now we have to apply it to both &lt;code&gt;m&lt;/code&gt; and
&lt;code&gt;a&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;As an example of using &lt;code&gt;assertStateless&lt;/code&gt;, let’s rewrite
the lifted &lt;code&gt;allocate&lt;/code&gt; function to include a single stateless
constraint:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb14&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb14-1&quot;&gt;&lt;a href=&quot;#cb14-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;allocateM&lt;/span&gt;
&lt;span id=&quot;cb14-2&quot;&gt;&lt;a href=&quot;#cb14-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;  ::&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;forall&lt;/span&gt; m a &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;MonadBaseControl&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;IO&lt;/span&gt; m, &lt;span class=&quot;dt&quot;&gt;MonadResource&lt;/span&gt; m, &lt;span class=&quot;dt&quot;&gt;Stateless&lt;/span&gt; m)&lt;/span&gt;
&lt;span id=&quot;cb14-3&quot;&gt;&lt;a href=&quot;#cb14-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;ot&quot;&gt;=&amp;gt;&lt;/span&gt; m a &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; (a &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; m ()) &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; m (&lt;span class=&quot;dt&quot;&gt;ReleaseKey&lt;/span&gt;, a)&lt;/span&gt;
&lt;span id=&quot;cb14-4&quot;&gt;&lt;a href=&quot;#cb14-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;allocateM acquire release &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb14-5&quot;&gt;&lt;a href=&quot;#cb14-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  assertStateless &lt;span class=&quot;op&quot;&gt;@&lt;/span&gt;a &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb14-6&quot;&gt;&lt;a href=&quot;#cb14-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  assertStateless &lt;span class=&quot;op&quot;&gt;@&lt;/span&gt;() &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb14-7&quot;&gt;&lt;a href=&quot;#cb14-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  assertStateless &lt;span class=&quot;op&quot;&gt;@&lt;/span&gt;(&lt;span class=&quot;dt&quot;&gt;ReleaseKey&lt;/span&gt;, a) &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb14-8&quot;&gt;&lt;a href=&quot;#cb14-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  liftBaseWith&lt;/span&gt;
&lt;span id=&quot;cb14-9&quot;&gt;&lt;a href=&quot;#cb14-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    (\runInIO &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; runInIO &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; allocate&lt;/span&gt;
&lt;span id=&quot;cb14-10&quot;&gt;&lt;a href=&quot;#cb14-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      (runInIO acquire)&lt;/span&gt;
&lt;span id=&quot;cb14-11&quot;&gt;&lt;a href=&quot;#cb14-11&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      (runInIO &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt; release))&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Here, &lt;code&gt;assertStateless&lt;/code&gt; generated all three
&lt;code&gt;StM m x ~ x&lt;/code&gt; constraints for us on the fly, from the single
universally-quantified constraint &lt;code&gt;Stateless m&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&quot;stateless-monad-transformers&quot;&gt;Stateless monad transformers&lt;/h2&gt;
&lt;p&gt;Let’s say we are writing a function that works in some stateless
monad, &lt;code&gt;m&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb15&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb15-1&quot;&gt;&lt;a href=&quot;#cb15-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;foo ::&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;MonadBaseControl&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;IO&lt;/span&gt; m, &lt;span class=&quot;dt&quot;&gt;MonadResource&lt;/span&gt; m, &lt;span class=&quot;dt&quot;&gt;Stateless&lt;/span&gt; m) &lt;span class=&quot;ot&quot;&gt;=&amp;gt;&lt;/span&gt; m ()&lt;/span&gt;
&lt;span id=&quot;cb15-2&quot;&gt;&lt;a href=&quot;#cb15-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;foo &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;...&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;But locally, it adds another layer on top of &lt;code&gt;m&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb16&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb16-1&quot;&gt;&lt;a href=&quot;#cb16-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;foo ::&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;MonadBaseControl&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;IO&lt;/span&gt; m, &lt;span class=&quot;dt&quot;&gt;MonadResource&lt;/span&gt; m, &lt;span class=&quot;dt&quot;&gt;Stateless&lt;/span&gt; m) &lt;span class=&quot;ot&quot;&gt;=&amp;gt;&lt;/span&gt; m ()&lt;/span&gt;
&lt;span id=&quot;cb16-2&quot;&gt;&lt;a href=&quot;#cb16-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;foo &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb16-3&quot;&gt;&lt;a href=&quot;#cb16-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  thing &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; getThing&lt;/span&gt;
&lt;span id=&quot;cb16-4&quot;&gt;&lt;a href=&quot;#cb16-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;fu&quot;&gt;flip&lt;/span&gt; runReaderT thing &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb16-5&quot;&gt;&lt;a href=&quot;#cb16-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;op&quot;&gt;...&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;And somewhere in there we need to allocate something:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb17&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb17-1&quot;&gt;&lt;a href=&quot;#cb17-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;foo ::&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;MonadBaseControl&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;IO&lt;/span&gt; m, &lt;span class=&quot;dt&quot;&gt;MonadResource&lt;/span&gt; m, &lt;span class=&quot;dt&quot;&gt;Stateless&lt;/span&gt; m) &lt;span class=&quot;ot&quot;&gt;=&amp;gt;&lt;/span&gt; m ()&lt;/span&gt;
&lt;span id=&quot;cb17-2&quot;&gt;&lt;a href=&quot;#cb17-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;foo &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb17-3&quot;&gt;&lt;a href=&quot;#cb17-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  thing &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; getThing&lt;/span&gt;
&lt;span id=&quot;cb17-4&quot;&gt;&lt;a href=&quot;#cb17-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;fu&quot;&gt;flip&lt;/span&gt; runReaderT thing &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb17-5&quot;&gt;&lt;a href=&quot;#cb17-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    resource &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; allocateM acq rel&lt;/span&gt;
&lt;span id=&quot;cb17-6&quot;&gt;&lt;a href=&quot;#cb17-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;op&quot;&gt;...&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The compiler won’t accept this, though:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;• Could not deduce: StM
                      m (Data.Constraint.Forall.Skolem (StatelessAt (ReaderT () m)))
                    ~
                    Data.Constraint.Forall.Skolem (StatelessAt (ReaderT () m))
    arising from a use of ‘allocateM’
  from the context: (MonadBaseControl IO m,
                     MonadResource m,
                     Stateless m)
    bound by the type signature for:
               foo :: (MonadBaseControl IO m, MonadResource m, Stateless m) =&amp;gt;
                      m ()&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In order to run &lt;code&gt;allocateM&lt;/code&gt; in the inner environment,
&lt;code&gt;ReaderT Thing m&lt;/code&gt;, we need to satisfy the constraint
&lt;code&gt;Stateless (ReaderT Thing)&lt;/code&gt;, which is different from the
&lt;code&gt;Stateless m&lt;/code&gt; that we have in scope.&lt;/p&gt;
&lt;p&gt;If the &lt;code&gt;acq&lt;/code&gt; and &lt;code&gt;rel&lt;/code&gt; actions do not need to
access the &lt;code&gt;thing&lt;/code&gt;, we can avoid the problem by lifting the
action to the outer environment:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb19&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb19-1&quot;&gt;&lt;a href=&quot;#cb19-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;foo ::&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;MonadBaseControl&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;IO&lt;/span&gt; m, &lt;span class=&quot;dt&quot;&gt;MonadResource&lt;/span&gt; m, &lt;span class=&quot;dt&quot;&gt;Stateless&lt;/span&gt; m) &lt;span class=&quot;ot&quot;&gt;=&amp;gt;&lt;/span&gt; m ()&lt;/span&gt;
&lt;span id=&quot;cb19-2&quot;&gt;&lt;a href=&quot;#cb19-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;foo &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb19-3&quot;&gt;&lt;a href=&quot;#cb19-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  thing &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; getThing&lt;/span&gt;
&lt;span id=&quot;cb19-4&quot;&gt;&lt;a href=&quot;#cb19-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;fu&quot;&gt;flip&lt;/span&gt; runReaderT thing &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb19-5&quot;&gt;&lt;a href=&quot;#cb19-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    resource &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; lift &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb19-6&quot;&gt;&lt;a href=&quot;#cb19-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;co&quot;&gt;-- this happens in m&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb19-7&quot;&gt;&lt;a href=&quot;#cb19-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      allocateM acq rel&lt;/span&gt;
&lt;span id=&quot;cb19-8&quot;&gt;&lt;a href=&quot;#cb19-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;op&quot;&gt;...&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;But what if &lt;code&gt;acq&lt;/code&gt; and &lt;code&gt;rel&lt;/code&gt; do need to know the
&lt;code&gt;thing&lt;/code&gt;?&lt;/p&gt;
&lt;p&gt;In that case, we need to prove to the compiler that for all
&lt;code&gt;m&lt;/code&gt;, &lt;code&gt;Stateless m&lt;/code&gt; implies
&lt;code&gt;Stateless (ReaderT Thing)&lt;/code&gt;. This should follow from the fact
that &lt;code&gt;ReaderT e&lt;/code&gt; is itself a “stateless transformer”, meaning
that it doesn’t change the state of the monad that it transforms. As
with &lt;code&gt;Stateless&lt;/code&gt;, we put this in the form of
partially-applicable class and then abstract over &lt;code&gt;a&lt;/code&gt; (and
&lt;code&gt;m&lt;/code&gt;):&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb20&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb20-1&quot;&gt;&lt;a href=&quot;#cb20-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;class&lt;/span&gt;    &lt;span class=&quot;dt&quot;&gt;StM&lt;/span&gt; (t m) a &lt;span class=&quot;op&quot;&gt;~&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;StM&lt;/span&gt; m a &lt;span class=&quot;ot&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;StatelessTAt&lt;/span&gt; t (&lt;span class=&quot;ot&quot;&gt;m ::&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;*&lt;/span&gt;) a&lt;/span&gt;
&lt;span id=&quot;cb20-2&quot;&gt;&lt;a href=&quot;#cb20-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;instance&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;StM&lt;/span&gt; (t m) a &lt;span class=&quot;op&quot;&gt;~&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;StM&lt;/span&gt; m a &lt;span class=&quot;ot&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;StatelessTAt&lt;/span&gt; t m a&lt;/span&gt;
&lt;span id=&quot;cb20-3&quot;&gt;&lt;a href=&quot;#cb20-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb20-4&quot;&gt;&lt;a href=&quot;#cb20-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;StatelessT&lt;/span&gt; t &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;ForallV&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;StatelessTAt&lt;/span&gt; t)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now we need to prove that &lt;code&gt;StatelessT t&lt;/code&gt; and
&lt;code&gt;Stateless m&lt;/code&gt; together imply &lt;code&gt;Stateless (t m)&lt;/code&gt;. In
the notation of the constraints package, this statement can be written
as&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb21&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb21-1&quot;&gt;&lt;a href=&quot;#cb21-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;statelessT ::&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;forall&lt;/span&gt; t m &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;StatelessT&lt;/span&gt; t, &lt;span class=&quot;dt&quot;&gt;Stateless&lt;/span&gt; m) &lt;span class=&quot;op&quot;&gt;:-&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Stateless&lt;/span&gt; (t m)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;How to prove it in Haskell is not completely obvious, and I recommend
that you try it yourself. I also posted a &lt;a
href=&quot;https://twitter.com/shebang/status/869843479177838592&quot;&gt;simplified
version of this exercise&lt;/a&gt; on twitter the other day.&lt;/p&gt;
&lt;p&gt;Anyway, here is one possible answer:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb22&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb22-1&quot;&gt;&lt;a href=&quot;#cb22-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;statelessT &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Sub&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;forall&lt;/span&gt; prf&lt;/span&gt;
&lt;span id=&quot;cb22-2&quot;&gt;&lt;a href=&quot;#cb22-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb22-3&quot;&gt;&lt;a href=&quot;#cb22-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;    prf ::&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;forall&lt;/span&gt; a &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;StatelessT&lt;/span&gt; t, &lt;span class=&quot;dt&quot;&gt;Stateless&lt;/span&gt; m) &lt;span class=&quot;ot&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Dict&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;StatelessAt&lt;/span&gt; (t m) a)&lt;/span&gt;
&lt;span id=&quot;cb22-4&quot;&gt;&lt;a href=&quot;#cb22-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    prf &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Dict&lt;/span&gt; \\ (&lt;span class=&quot;ot&quot;&gt;instV ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;StatelessT&lt;/span&gt; t &lt;span class=&quot;op&quot;&gt;:-&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;StatelessTAt&lt;/span&gt; t m a)&lt;/span&gt;
&lt;span id=&quot;cb22-5&quot;&gt;&lt;a href=&quot;#cb22-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;               \\ (&lt;span class=&quot;ot&quot;&gt;inst  ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Stateless&lt;/span&gt; m  &lt;span class=&quot;op&quot;&gt;:-&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;StatelessAt&lt;/span&gt; m a)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Finally, here is a function analogous to &lt;code&gt;assertStateless&lt;/code&gt;
that brings the &lt;code&gt;Stateless (t m)&lt;/code&gt; constraint into scope:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb23&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb23-1&quot;&gt;&lt;a href=&quot;#cb23-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;liftStatelessT&lt;/span&gt;
&lt;span id=&quot;cb23-2&quot;&gt;&lt;a href=&quot;#cb23-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;  ::&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;forall&lt;/span&gt; t m b &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;StatelessT&lt;/span&gt; t, &lt;span class=&quot;dt&quot;&gt;Stateless&lt;/span&gt; m)&lt;/span&gt;
&lt;span id=&quot;cb23-3&quot;&gt;&lt;a href=&quot;#cb23-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;ot&quot;&gt;=&amp;gt;&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;Stateless&lt;/span&gt; (t m) &lt;span class=&quot;ot&quot;&gt;=&amp;gt;&lt;/span&gt; (t m) b) &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; (t m) b&lt;/span&gt;
&lt;span id=&quot;cb23-4&quot;&gt;&lt;a href=&quot;#cb23-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;liftStatelessT action &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; action \\ statelessT &lt;span class=&quot;op&quot;&gt;@&lt;/span&gt;t &lt;span class=&quot;op&quot;&gt;@&lt;/span&gt;m&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;And here is a minimal working example that demonstrates the usage of
&lt;code&gt;liftStatelessT&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb24&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb24-1&quot;&gt;&lt;a href=&quot;#cb24-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;foo ::&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;MonadBaseControl&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;IO&lt;/span&gt; m, &lt;span class=&quot;dt&quot;&gt;MonadResource&lt;/span&gt; m, &lt;span class=&quot;dt&quot;&gt;Stateless&lt;/span&gt; m) &lt;span class=&quot;ot&quot;&gt;=&amp;gt;&lt;/span&gt; m ()&lt;/span&gt;
&lt;span id=&quot;cb24-2&quot;&gt;&lt;a href=&quot;#cb24-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;foo &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb24-3&quot;&gt;&lt;a href=&quot;#cb24-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;fu&quot;&gt;flip&lt;/span&gt; runReaderT () &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; liftStatelessT &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb24-4&quot;&gt;&lt;a href=&quot;#cb24-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    resource &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; allocateM (&lt;span class=&quot;fu&quot;&gt;return&lt;/span&gt; ()) (&lt;span class=&quot;fu&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;return&lt;/span&gt; ())&lt;/span&gt;
&lt;span id=&quot;cb24-5&quot;&gt;&lt;a href=&quot;#cb24-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;fu&quot;&gt;return&lt;/span&gt; ()&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;monad-unlift&quot;&gt;monad-unlift&lt;/h2&gt;
&lt;p&gt;After this article was originally published, MitchellSalad &lt;a
href=&quot;https://www.reddit.com/r/haskell/comments/6fcl9z/universally_stateless_monads/dihilhy/&quot;&gt;pointed
out&lt;/a&gt; the &lt;a
href=&quot;https://www.fpcomplete.com/blog/2015/04/announcing-monad-unlift&quot;&gt;monad-unlift
library&lt;/a&gt;, which Michael Snoyman announced two years earlier, and
which I was not aware of.&lt;/p&gt;
&lt;p&gt;Indeed, Stateless and monad-unlift (v0.2.0) are strikingly
similar.&lt;/p&gt;
&lt;p&gt;(“Stateless” is the name of the code and the module described in this
article. You can find the contents of the module below. I have not
published it on github or hackage.)&lt;/p&gt;
&lt;p&gt;But here are some important differences.&lt;/p&gt;
&lt;h3 id=&quot;the-interface&quot;&gt;the interface&lt;/h3&gt;
&lt;p&gt;With Stateless, we use the normal &lt;code&gt;MonadBaseControl&lt;/code&gt;
functions (like &lt;code&gt;liftBaseWith&lt;/code&gt;) and then turn
&lt;code&gt;StM m a&lt;/code&gt; into &lt;code&gt;a&lt;/code&gt; with
&lt;code&gt;assertStateless&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;With monad-unlift, we call &lt;code&gt;askUnliftBase&lt;/code&gt; or
&lt;code&gt;askRunBase&lt;/code&gt; &lt;em&gt;instead of&lt;/em&gt;
&lt;code&gt;liftBaseWith&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;For comparison, here is &lt;code&gt;allocateM&lt;/code&gt; implemented with both
approaches:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb25&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb25-1&quot;&gt;&lt;a href=&quot;#cb25-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;co&quot;&gt;-- Stateless&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb25-2&quot;&gt;&lt;a href=&quot;#cb25-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;allocateM&lt;/span&gt;
&lt;span id=&quot;cb25-3&quot;&gt;&lt;a href=&quot;#cb25-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;  ::&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;forall&lt;/span&gt; m a &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;MonadBaseControl&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;IO&lt;/span&gt; m, &lt;span class=&quot;dt&quot;&gt;MonadResource&lt;/span&gt; m, &lt;span class=&quot;dt&quot;&gt;Stateless&lt;/span&gt; m)&lt;/span&gt;
&lt;span id=&quot;cb25-4&quot;&gt;&lt;a href=&quot;#cb25-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;ot&quot;&gt;=&amp;gt;&lt;/span&gt; m a &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; (a &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; m ()) &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; m (&lt;span class=&quot;dt&quot;&gt;ReleaseKey&lt;/span&gt;, a)&lt;/span&gt;
&lt;span id=&quot;cb25-5&quot;&gt;&lt;a href=&quot;#cb25-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;allocateM acquire release &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb25-6&quot;&gt;&lt;a href=&quot;#cb25-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  assertStateless &lt;span class=&quot;op&quot;&gt;@&lt;/span&gt;a &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb25-7&quot;&gt;&lt;a href=&quot;#cb25-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  assertStateless &lt;span class=&quot;op&quot;&gt;@&lt;/span&gt;() &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb25-8&quot;&gt;&lt;a href=&quot;#cb25-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  assertStateless &lt;span class=&quot;op&quot;&gt;@&lt;/span&gt;(&lt;span class=&quot;dt&quot;&gt;ReleaseKey&lt;/span&gt;, a) &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb25-9&quot;&gt;&lt;a href=&quot;#cb25-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  liftBaseWith&lt;/span&gt;
&lt;span id=&quot;cb25-10&quot;&gt;&lt;a href=&quot;#cb25-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    (\runInIO &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; runInIO &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; allocate&lt;/span&gt;
&lt;span id=&quot;cb25-11&quot;&gt;&lt;a href=&quot;#cb25-11&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      (runInIO acquire)&lt;/span&gt;
&lt;span id=&quot;cb25-12&quot;&gt;&lt;a href=&quot;#cb25-12&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      (runInIO &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt; release))&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb26&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb26-1&quot;&gt;&lt;a href=&quot;#cb26-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;co&quot;&gt;-- monad-unlift&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb26-2&quot;&gt;&lt;a href=&quot;#cb26-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;allocateM&lt;/span&gt;
&lt;span id=&quot;cb26-3&quot;&gt;&lt;a href=&quot;#cb26-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;  ::&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;forall&lt;/span&gt; m a &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;MonadBaseUnlift&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;IO&lt;/span&gt; m, &lt;span class=&quot;dt&quot;&gt;MonadResource&lt;/span&gt; m)&lt;/span&gt;
&lt;span id=&quot;cb26-4&quot;&gt;&lt;a href=&quot;#cb26-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;ot&quot;&gt;=&amp;gt;&lt;/span&gt; m a &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; (a &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; m ()) &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; m (&lt;span class=&quot;dt&quot;&gt;ReleaseKey&lt;/span&gt;, a)&lt;/span&gt;
&lt;span id=&quot;cb26-5&quot;&gt;&lt;a href=&quot;#cb26-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;allocateM acquire release &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb26-6&quot;&gt;&lt;a href=&quot;#cb26-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;dt&quot;&gt;UnliftBase&lt;/span&gt; runInIO &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; askUnliftBase&lt;/span&gt;
&lt;span id=&quot;cb26-7&quot;&gt;&lt;a href=&quot;#cb26-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  allocate&lt;/span&gt;
&lt;span id=&quot;cb26-8&quot;&gt;&lt;a href=&quot;#cb26-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    (runInIO acquire)&lt;/span&gt;
&lt;span id=&quot;cb26-9&quot;&gt;&lt;a href=&quot;#cb26-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    (runInIO &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt; release)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The monad-lift version is simpler and more concise despite (but, in
fact, thanks to) the &lt;code&gt;UnliftBase&lt;/code&gt; wrapper.&lt;/p&gt;
&lt;p&gt;On the other hand, Stateless integrates better with the other code
built on top of monad-control. If we have a third-party “lifted” library
whose function returns &lt;code&gt;m (StM m a)&lt;/code&gt;, Stateless allows us to
simplify that down to &lt;code&gt;m a&lt;/code&gt;. With monad-unlift, we would have
to re-implement the whole function to use different primitives.&lt;/p&gt;
&lt;h3 id=&quot;dealing-with-transformers&quot;&gt;dealing with transformers&lt;/h3&gt;
&lt;p&gt;The approach to transformers also differs between the libraries. With
Stateless, we stay on the transformer level and prove that it is
stateless:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb27&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb27-1&quot;&gt;&lt;a href=&quot;#cb27-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;foo ::&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;forall&lt;/span&gt; m &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;MonadBaseControl&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;IO&lt;/span&gt; m, &lt;span class=&quot;dt&quot;&gt;MonadResource&lt;/span&gt; m, &lt;span class=&quot;dt&quot;&gt;Stateless&lt;/span&gt; m) &lt;span class=&quot;ot&quot;&gt;=&amp;gt;&lt;/span&gt; m ()&lt;/span&gt;
&lt;span id=&quot;cb27-2&quot;&gt;&lt;a href=&quot;#cb27-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;foo &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb27-3&quot;&gt;&lt;a href=&quot;#cb27-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;fu&quot;&gt;flip&lt;/span&gt; runReaderT () &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; liftStatelessT &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb27-4&quot;&gt;&lt;a href=&quot;#cb27-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    resource &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; allocateM acq rel&lt;/span&gt;
&lt;span id=&quot;cb27-5&quot;&gt;&lt;a href=&quot;#cb27-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;fu&quot;&gt;return&lt;/span&gt; ()&lt;/span&gt;
&lt;span id=&quot;cb27-6&quot;&gt;&lt;a href=&quot;#cb27-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb27-7&quot;&gt;&lt;a href=&quot;#cb27-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;    acq ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;ReaderT&lt;/span&gt; () m ()&lt;/span&gt;
&lt;span id=&quot;cb27-8&quot;&gt;&lt;a href=&quot;#cb27-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    acq &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;return&lt;/span&gt; ()&lt;/span&gt;
&lt;span id=&quot;cb27-9&quot;&gt;&lt;a href=&quot;#cb27-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;    rel ::&lt;/span&gt; () &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;ReaderT&lt;/span&gt; () m ()&lt;/span&gt;
&lt;span id=&quot;cb27-10&quot;&gt;&lt;a href=&quot;#cb27-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    rel _ &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;return&lt;/span&gt; ()&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;With monad-unlift, we bring everything down into the untransformed
monad:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb28&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb28-1&quot;&gt;&lt;a href=&quot;#cb28-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;foo ::&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;forall&lt;/span&gt; m &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;MonadBaseUnlift&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;IO&lt;/span&gt; m, &lt;span class=&quot;dt&quot;&gt;MonadResource&lt;/span&gt; m) &lt;span class=&quot;ot&quot;&gt;=&amp;gt;&lt;/span&gt; m ()&lt;/span&gt;
&lt;span id=&quot;cb28-2&quot;&gt;&lt;a href=&quot;#cb28-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;foo &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb28-3&quot;&gt;&lt;a href=&quot;#cb28-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;fu&quot;&gt;flip&lt;/span&gt; runReaderT () &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb28-4&quot;&gt;&lt;a href=&quot;#cb28-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;dt&quot;&gt;Unlift&lt;/span&gt; run &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; askUnlift&lt;/span&gt;
&lt;span id=&quot;cb28-5&quot;&gt;&lt;a href=&quot;#cb28-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    resource &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; lift &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; allocateM (run acq) (run &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt; rel)&lt;/span&gt;
&lt;span id=&quot;cb28-6&quot;&gt;&lt;a href=&quot;#cb28-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;fu&quot;&gt;return&lt;/span&gt; ()&lt;/span&gt;
&lt;span id=&quot;cb28-7&quot;&gt;&lt;a href=&quot;#cb28-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb28-8&quot;&gt;&lt;a href=&quot;#cb28-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;    acq ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;ReaderT&lt;/span&gt; () m ()&lt;/span&gt;
&lt;span id=&quot;cb28-9&quot;&gt;&lt;a href=&quot;#cb28-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    acq &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;return&lt;/span&gt; ()&lt;/span&gt;
&lt;span id=&quot;cb28-10&quot;&gt;&lt;a href=&quot;#cb28-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;    rel ::&lt;/span&gt; () &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;ReaderT&lt;/span&gt; () m ()&lt;/span&gt;
&lt;span id=&quot;cb28-11&quot;&gt;&lt;a href=&quot;#cb28-11&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    rel _ &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;return&lt;/span&gt; ()&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;If you call &lt;code&gt;allocateM&lt;/code&gt; many times in the same function,
“running” everything with monad-unlift may become tedious, but otherwise
both approaches are workable.&lt;/p&gt;
&lt;p&gt;Here is a case where &lt;code&gt;monad-unlift&lt;/code&gt; would not work,
however. Consider a function&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb29&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb29-1&quot;&gt;&lt;a href=&quot;#cb29-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;bar ::&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;MonadBaseUnlift&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;IO&lt;/span&gt; m, &lt;span class=&quot;dt&quot;&gt;MonadReader&lt;/span&gt; () m) &lt;span class=&quot;ot&quot;&gt;=&amp;gt;&lt;/span&gt; m ()&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The signature seems reasonable: the function needs to run in a
stateless monad so that it can do something like &lt;code&gt;allocateM&lt;/code&gt;
internally; it also needs access to some configuration parameter, which
I replaced with &lt;code&gt;()&lt;/code&gt; for simplicity.&lt;/p&gt;
&lt;p&gt;We want to call &lt;code&gt;bar&lt;/code&gt; from a monad-polymorphic function
&lt;code&gt;foo&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb30&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb30-1&quot;&gt;&lt;a href=&quot;#cb30-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;foo ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;MonadBaseUnlift&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;IO&lt;/span&gt; m &lt;span class=&quot;ot&quot;&gt;=&amp;gt;&lt;/span&gt; m ()&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;We can’t call &lt;code&gt;bar&lt;/code&gt; directly because the
&lt;code&gt;MonadReader&lt;/code&gt; constraint will not be satisfied. But if we add
a &lt;code&gt;ReaderT&lt;/code&gt; layer to satisfy it,&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb31&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb31-1&quot;&gt;&lt;a href=&quot;#cb31-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;foo ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;MonadBaseUnlift&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;IO&lt;/span&gt; m &lt;span class=&quot;ot&quot;&gt;=&amp;gt;&lt;/span&gt; m ()&lt;/span&gt;
&lt;span id=&quot;cb31-2&quot;&gt;&lt;a href=&quot;#cb31-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;foo &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; runReaderT bar ()&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;… then &lt;code&gt;bar&lt;/code&gt;’s &lt;code&gt;MonadBaseUnlift&lt;/code&gt; constraint is
no longer satisfied.&lt;/p&gt;
&lt;p&gt;There is just no reasonable way to do this with monad-unlift, as far
as I can tell. With Stateless, this becomes trivial:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb32&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb32-1&quot;&gt;&lt;a href=&quot;#cb32-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;bar ::&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;Stateless&lt;/span&gt; m, &lt;span class=&quot;dt&quot;&gt;MonadReader&lt;/span&gt; () m) &lt;span class=&quot;ot&quot;&gt;=&amp;gt;&lt;/span&gt; m ()&lt;/span&gt;
&lt;span id=&quot;cb32-2&quot;&gt;&lt;a href=&quot;#cb32-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;bar &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;return&lt;/span&gt; ()&lt;/span&gt;
&lt;span id=&quot;cb32-3&quot;&gt;&lt;a href=&quot;#cb32-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb32-4&quot;&gt;&lt;a href=&quot;#cb32-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;foo ::&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;Monad&lt;/span&gt; m, &lt;span class=&quot;dt&quot;&gt;Stateless&lt;/span&gt; m) &lt;span class=&quot;ot&quot;&gt;=&amp;gt;&lt;/span&gt; m ()&lt;/span&gt;
&lt;span id=&quot;cb32-5&quot;&gt;&lt;a href=&quot;#cb32-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;foo &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; runReaderT (liftStatelessT bar) ()&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;unliftio&quot;&gt;unliftio&lt;/h2&gt;
&lt;p&gt;Just a couple of weeks after this article was originally published,
&lt;a
href=&quot;https://www.fpcomplete.com/blog/2017/07/announcing-new-unliftio-library&quot;&gt;Michael
announced&lt;/a&gt; another library in this space: unliftio.&lt;/p&gt;
&lt;p&gt;There are two main differences between unliftio and
monad-unlift/Stateless:&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;The base monad is always IO, as the package name implies.&lt;/li&gt;
&lt;li&gt;Instead of relying on &lt;code&gt;monad-control&lt;/code&gt; to provide the
instances for various transformers, and on libraries such as
&lt;code&gt;lifted-base&lt;/code&gt; and &lt;code&gt;lifted-async&lt;/code&gt; to provide the
lifted versions of the standard functions, it builds its own
ecosystem.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;I considered doing roughly the same when I wrote Stateless, but
decided against it, as it meant writing more code. But now that Michael
bit the bullet, there is no reason not to take advantage of his
work.&lt;/p&gt;
&lt;p&gt;There are plenty of reasons to prefer the specialized version:
simpler and easier to understand types, better type error messages,
better type inference, easier deriving (due to the absence of associated
types), and no complications with monad transformers.&lt;/p&gt;
&lt;p&gt;So, &lt;a href=&quot;https://www.stackage.org/package/unliftio&quot;&gt;unliftio&lt;/a&gt;
is what I would recommend today over Stateless or monad-unlift.&lt;/p&gt;
&lt;h2 id=&quot;complete-code-for-stateless&quot;&gt;Complete code for Stateless&lt;/h2&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb33&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb33-1&quot;&gt;&lt;a href=&quot;#cb33-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;co&quot;&gt;-- (c) Roman Cheplyaka, 2017. License: MIT&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb33-2&quot;&gt;&lt;a href=&quot;#cb33-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;{-# LANGUAGE GADTs, ConstraintKinds, MultiParamTypeClasses, FlexibleInstances,&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb33-3&quot;&gt;&lt;a href=&quot;#cb33-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;             ScopedTypeVariables, RankNTypes, AllowAmbiguousTypes,&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb33-4&quot;&gt;&lt;a href=&quot;#cb33-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;             TypeApplications, TypeOperators, KindSignatures,&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb33-5&quot;&gt;&lt;a href=&quot;#cb33-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;             UndecidableInstances, UndecidableSuperClasses #-}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb33-6&quot;&gt;&lt;a href=&quot;#cb33-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb33-7&quot;&gt;&lt;a href=&quot;#cb33-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;module&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Stateless&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb33-8&quot;&gt;&lt;a href=&quot;#cb33-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb33-9&quot;&gt;&lt;a href=&quot;#cb33-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Data.Constraint&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb33-10&quot;&gt;&lt;a href=&quot;#cb33-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Data.Constraint.Forall&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb33-11&quot;&gt;&lt;a href=&quot;#cb33-11&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Control.Monad.Trans.Control&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb33-12&quot;&gt;&lt;a href=&quot;#cb33-12&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb33-13&quot;&gt;&lt;a href=&quot;#cb33-13&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;class&lt;/span&gt;    &lt;span class=&quot;dt&quot;&gt;StM&lt;/span&gt; m a &lt;span class=&quot;op&quot;&gt;~&lt;/span&gt; a &lt;span class=&quot;ot&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;StatelessAt&lt;/span&gt; m a&lt;/span&gt;
&lt;span id=&quot;cb33-14&quot;&gt;&lt;a href=&quot;#cb33-14&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;instance&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;StM&lt;/span&gt; m a &lt;span class=&quot;op&quot;&gt;~&lt;/span&gt; a &lt;span class=&quot;ot&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;StatelessAt&lt;/span&gt; m a&lt;/span&gt;
&lt;span id=&quot;cb33-15&quot;&gt;&lt;a href=&quot;#cb33-15&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb33-16&quot;&gt;&lt;a href=&quot;#cb33-16&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;co&quot;&gt;-- | A constraint that asserts that a given monad is stateless&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb33-17&quot;&gt;&lt;a href=&quot;#cb33-17&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Stateless&lt;/span&gt; m &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Forall&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;StatelessAt&lt;/span&gt; m)&lt;/span&gt;
&lt;span id=&quot;cb33-18&quot;&gt;&lt;a href=&quot;#cb33-18&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb33-19&quot;&gt;&lt;a href=&quot;#cb33-19&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;co&quot;&gt;-- | Instantiate the stateless claim at a particular monad and type&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb33-20&quot;&gt;&lt;a href=&quot;#cb33-20&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;assertStateless ::&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;forall&lt;/span&gt; a m b &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Stateless&lt;/span&gt; m &lt;span class=&quot;ot&quot;&gt;=&amp;gt;&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;StM&lt;/span&gt; m a &lt;span class=&quot;op&quot;&gt;~&lt;/span&gt; a &lt;span class=&quot;ot&quot;&gt;=&amp;gt;&lt;/span&gt; m b) &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; m b&lt;/span&gt;
&lt;span id=&quot;cb33-21&quot;&gt;&lt;a href=&quot;#cb33-21&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;assertStateless action &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; action \\ (&lt;span class=&quot;ot&quot;&gt;inst ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Stateless&lt;/span&gt; m &lt;span class=&quot;op&quot;&gt;:-&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;StatelessAt&lt;/span&gt; m a)&lt;/span&gt;
&lt;span id=&quot;cb33-22&quot;&gt;&lt;a href=&quot;#cb33-22&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb33-23&quot;&gt;&lt;a href=&quot;#cb33-23&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;class&lt;/span&gt;    &lt;span class=&quot;dt&quot;&gt;StM&lt;/span&gt; (t m) a &lt;span class=&quot;op&quot;&gt;~&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;StM&lt;/span&gt; m a &lt;span class=&quot;ot&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;StatelessTAt&lt;/span&gt; t (&lt;span class=&quot;ot&quot;&gt;m ::&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;*&lt;/span&gt;) a&lt;/span&gt;
&lt;span id=&quot;cb33-24&quot;&gt;&lt;a href=&quot;#cb33-24&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;instance&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;StM&lt;/span&gt; (t m) a &lt;span class=&quot;op&quot;&gt;~&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;StM&lt;/span&gt; m a &lt;span class=&quot;ot&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;StatelessTAt&lt;/span&gt; t m a&lt;/span&gt;
&lt;span id=&quot;cb33-25&quot;&gt;&lt;a href=&quot;#cb33-25&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb33-26&quot;&gt;&lt;a href=&quot;#cb33-26&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;co&quot;&gt;-- | A statement that a monad transformer doesn&amp;#39;t alter the state type&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb33-27&quot;&gt;&lt;a href=&quot;#cb33-27&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;StatelessT&lt;/span&gt; t &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;ForallV&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;StatelessTAt&lt;/span&gt; t)&lt;/span&gt;
&lt;span id=&quot;cb33-28&quot;&gt;&lt;a href=&quot;#cb33-28&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb33-29&quot;&gt;&lt;a href=&quot;#cb33-29&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;co&quot;&gt;-- | A proof that if @t@ is a stateless transformer and @m@ is a stateless monad,&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb33-30&quot;&gt;&lt;a href=&quot;#cb33-30&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;co&quot;&gt;-- then @t m@ is a stateless monad&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb33-31&quot;&gt;&lt;a href=&quot;#cb33-31&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;statelessT ::&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;forall&lt;/span&gt; t m &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;StatelessT&lt;/span&gt; t, &lt;span class=&quot;dt&quot;&gt;Stateless&lt;/span&gt; m) &lt;span class=&quot;op&quot;&gt;:-&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Stateless&lt;/span&gt; (t m)&lt;/span&gt;
&lt;span id=&quot;cb33-32&quot;&gt;&lt;a href=&quot;#cb33-32&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;statelessT &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Sub&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;forall&lt;/span&gt; prf&lt;/span&gt;
&lt;span id=&quot;cb33-33&quot;&gt;&lt;a href=&quot;#cb33-33&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb33-34&quot;&gt;&lt;a href=&quot;#cb33-34&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;    prf ::&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;forall&lt;/span&gt; a &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;StatelessT&lt;/span&gt; t, &lt;span class=&quot;dt&quot;&gt;Stateless&lt;/span&gt; m) &lt;span class=&quot;ot&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Dict&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;StatelessAt&lt;/span&gt; (t m) a)&lt;/span&gt;
&lt;span id=&quot;cb33-35&quot;&gt;&lt;a href=&quot;#cb33-35&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    prf &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Dict&lt;/span&gt; \\ (&lt;span class=&quot;ot&quot;&gt;instV ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;StatelessT&lt;/span&gt; t &lt;span class=&quot;op&quot;&gt;:-&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;StatelessTAt&lt;/span&gt; t m a)&lt;/span&gt;
&lt;span id=&quot;cb33-36&quot;&gt;&lt;a href=&quot;#cb33-36&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;               \\ (&lt;span class=&quot;ot&quot;&gt;inst  ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Stateless&lt;/span&gt; m  &lt;span class=&quot;op&quot;&gt;:-&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;StatelessAt&lt;/span&gt; m a)&lt;/span&gt;
&lt;span id=&quot;cb33-37&quot;&gt;&lt;a href=&quot;#cb33-37&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb33-38&quot;&gt;&lt;a href=&quot;#cb33-38&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;co&quot;&gt;-- | Derive the &amp;#39;Stateless&amp;#39; constraint for a transformed monad @t m@&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb33-39&quot;&gt;&lt;a href=&quot;#cb33-39&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;liftStatelessT&lt;/span&gt;
&lt;span id=&quot;cb33-40&quot;&gt;&lt;a href=&quot;#cb33-40&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;  ::&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;forall&lt;/span&gt; t m b &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;StatelessT&lt;/span&gt; t, &lt;span class=&quot;dt&quot;&gt;Stateless&lt;/span&gt; m)&lt;/span&gt;
&lt;span id=&quot;cb33-41&quot;&gt;&lt;a href=&quot;#cb33-41&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;ot&quot;&gt;=&amp;gt;&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;Stateless&lt;/span&gt; (t m) &lt;span class=&quot;ot&quot;&gt;=&amp;gt;&lt;/span&gt; (t m) b) &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; (t m) b&lt;/span&gt;
&lt;span id=&quot;cb33-42&quot;&gt;&lt;a href=&quot;#cb33-42&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;liftStatelessT action &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; action \\ statelessT &lt;span class=&quot;op&quot;&gt;@&lt;/span&gt;t &lt;span class=&quot;op&quot;&gt;@&lt;/span&gt;m&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
</description>
                        <pubDate>Sun, 04 Jun 2017 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2017-06-04-universally-stateless-monads</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2017-06-04-universally-stateless-monads.html</guid>
                </item>
        
                <item>
                        <title>Why your podcast needs https</title>
                        <description>&lt;p&gt;Modern browsers warn users when they attempt to send data over an
unencrypted http connection. This seems to have been effective, and most
dynamic websites today are served over https.&lt;/p&gt;
&lt;p&gt;But what if you are setting up a simple static blog or podcast
website? Is it worth bothering with https, or is it above your paranoia
level?&lt;/p&gt;
&lt;p&gt;There are several reasons to use https even for a simple static site:
for instance, to prevent &lt;a
href=&quot;https://arstechnica.com/tech-policy/2013/04/how-a-banner-ad-for-hs-ok/&quot;&gt;ad
injection by ISPs&lt;/a&gt;. You can easily imagine something even more
nefarious, such as an &lt;a
href=&quot;https://en.wikipedia.org/wiki/Evil_twin_(wireless_networks)&quot;&gt;evil
twin hotspot&lt;/a&gt; in a popular San Francisco coffee shop &lt;a
href=&quot;https://thejh.net/misc/website-terminal-copy-paste&quot;&gt;invisibly&lt;/a&gt;
adding malicious code to snippets that patrons copy-paste from unsecured
blogs.&lt;/p&gt;
&lt;p&gt;Yesterday I was at the Euston station in London waiting for a train.
There were advertisements for free WiFi all over the place, to which I
gratefully connected. I had recently discovered a new podcast, and I
queued several episodes to listen to during the 2.5 hour ride.&lt;/p&gt;
&lt;p&gt;The episodes downloaded very quickly, but when I tried to listen to
them, they would not play.&lt;/p&gt;
&lt;p&gt;It turned out that the free WiFi at Euston isn’t free
&lt;em&gt;internet&lt;/em&gt;; it’s a local network where you can watch ads and read
magazines. All traffic, including requests for the mp3 files from my
podcatcher, were redirected to their captive portal.&lt;/p&gt;
&lt;p&gt;If the links in the podcast’s RSS feed were https links, the program
would probably refuse to download the files when presented with no or
invalid TLS certificate. (To be fair, it could have also looked at the
content type of the files, which was probably
&lt;code&gt;text/html&lt;/code&gt;.)&lt;/p&gt;
&lt;p&gt;But instead, the program simply downloaded the webpage thinking it
was an mp3 file. So I had to undo this later by figuring out which
episodes were corrupted (some I had downloaded earlier, and they were
valid) and how to trigger their re-downloading.&lt;/p&gt;
&lt;p&gt;So if you have a podcast, &lt;a
href=&quot;https://letsencrypt.org/getting-started/&quot;&gt;configure&lt;/a&gt; https on
your host and make all links (especially in the RSS feed) https links.
If you don’t do that, some of your listeners may hear &lt;a
href=&quot;http://bit.ly/2qOkYoD&quot;&gt;this&lt;/a&gt; instead of your voice.&lt;/p&gt;
</description>
                        <pubDate>Mon, 22 May 2017 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2017-05-22-why-your-podcast-needs-https</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2017-05-22-why-your-podcast-needs-https.html</guid>
                </item>
        
                <item>
                        <title>Convert time interval to number in R</title>
                        <description>&lt;p&gt;Let’s say you have two time values in R, &lt;code&gt;t1&lt;/code&gt; and
&lt;code&gt;t2&lt;/code&gt;, and you want to compute the distance between them.&lt;/p&gt;
&lt;p&gt;A natural thing to try would be&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb1&quot;&gt;&lt;pre class=&quot;sourceCode r&quot;&gt;&lt;code class=&quot;sourceCode r&quot;&gt;&lt;span id=&quot;cb1-1&quot;&gt;&lt;a href=&quot;#cb1-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;fu&quot;&gt;as.numeric&lt;/span&gt;(t1&lt;span class=&quot;sc&quot;&gt;-&lt;/span&gt;t2)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This should &lt;em&gt;probably&lt;/em&gt; return a number in seconds, but it
&lt;em&gt;might&lt;/em&gt; be in some other units, so you test just to be safe:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb2&quot;&gt;&lt;pre class=&quot;sourceCode r&quot;&gt;&lt;code class=&quot;sourceCode r&quot;&gt;&lt;span id=&quot;cb2-1&quot;&gt;&lt;a href=&quot;#cb2-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;sc&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;as.numeric&lt;/span&gt;(&lt;span class=&quot;fu&quot;&gt;as.POSIXct&lt;/span&gt;(&lt;span class=&quot;st&quot;&gt;&amp;quot;2017-05-17 19:00:10&amp;quot;&lt;/span&gt;)&lt;span class=&quot;sc&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;as.POSIXct&lt;/span&gt;(&lt;span class=&quot;st&quot;&gt;&amp;quot;2017-05-17 19:00:00&amp;quot;&lt;/span&gt;))&lt;/span&gt;
&lt;span id=&quot;cb2-2&quot;&gt;&lt;a href=&quot;#cb2-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;[&lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;] &lt;span class=&quot;dv&quot;&gt;10&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;“Ok,” you think, “seconds it is,” and proceed to use an expression
like the above in your code.&lt;/p&gt;
&lt;p&gt;You just fell victim to an incredibly nasty “feature” of the R
date/time API. The &lt;code&gt;as.numeric&lt;/code&gt; and other similar functions
actually choose the units based on the length of the interval by
default:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb3&quot;&gt;&lt;pre class=&quot;sourceCode r&quot;&gt;&lt;code class=&quot;sourceCode r&quot;&gt;&lt;span id=&quot;cb3-1&quot;&gt;&lt;a href=&quot;#cb3-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;sc&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;as.numeric&lt;/span&gt;(&lt;span class=&quot;fu&quot;&gt;as.POSIXct&lt;/span&gt;(&lt;span class=&quot;st&quot;&gt;&amp;quot;2007-05-07 09:00:10&amp;quot;&lt;/span&gt;)&lt;span class=&quot;sc&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;as.POSIXct&lt;/span&gt;(&lt;span class=&quot;st&quot;&gt;&amp;quot;2007-05-07 09:00:00&amp;quot;&lt;/span&gt;))&lt;/span&gt;
&lt;span id=&quot;cb3-2&quot;&gt;&lt;a href=&quot;#cb3-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;[&lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;] &lt;span class=&quot;dv&quot;&gt;10&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-3&quot;&gt;&lt;a href=&quot;#cb3-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;sc&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;as.numeric&lt;/span&gt;(&lt;span class=&quot;fu&quot;&gt;as.POSIXct&lt;/span&gt;(&lt;span class=&quot;st&quot;&gt;&amp;quot;2007-05-07 09:10:00&amp;quot;&lt;/span&gt;)&lt;span class=&quot;sc&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;as.POSIXct&lt;/span&gt;(&lt;span class=&quot;st&quot;&gt;&amp;quot;2007-05-07 09:00:00&amp;quot;&lt;/span&gt;))&lt;/span&gt;
&lt;span id=&quot;cb3-4&quot;&gt;&lt;a href=&quot;#cb3-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;[&lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;] &lt;span class=&quot;dv&quot;&gt;10&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-5&quot;&gt;&lt;a href=&quot;#cb3-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;sc&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;as.numeric&lt;/span&gt;(&lt;span class=&quot;fu&quot;&gt;as.POSIXct&lt;/span&gt;(&lt;span class=&quot;st&quot;&gt;&amp;quot;2007-05-07 19:00:00&amp;quot;&lt;/span&gt;)&lt;span class=&quot;sc&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;as.POSIXct&lt;/span&gt;(&lt;span class=&quot;st&quot;&gt;&amp;quot;2007-05-07 09:00:00&amp;quot;&lt;/span&gt;))&lt;/span&gt;
&lt;span id=&quot;cb3-6&quot;&gt;&lt;a href=&quot;#cb3-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;[&lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;] &lt;span class=&quot;dv&quot;&gt;10&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-7&quot;&gt;&lt;a href=&quot;#cb3-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;sc&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;as.numeric&lt;/span&gt;(&lt;span class=&quot;fu&quot;&gt;as.POSIXct&lt;/span&gt;(&lt;span class=&quot;st&quot;&gt;&amp;quot;2007-05-17 09:00:00&amp;quot;&lt;/span&gt;)&lt;span class=&quot;sc&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;as.POSIXct&lt;/span&gt;(&lt;span class=&quot;st&quot;&gt;&amp;quot;2007-05-07 09:00:00&amp;quot;&lt;/span&gt;))&lt;/span&gt;
&lt;span id=&quot;cb3-8&quot;&gt;&lt;a href=&quot;#cb3-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;[&lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;] &lt;span class=&quot;dv&quot;&gt;10&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;To get a consistent behavior, you need to specify the units,
e.g.:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb4&quot;&gt;&lt;pre class=&quot;sourceCode r&quot;&gt;&lt;code class=&quot;sourceCode r&quot;&gt;&lt;span id=&quot;cb4-1&quot;&gt;&lt;a href=&quot;#cb4-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;sc&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;as.numeric&lt;/span&gt;(&lt;span class=&quot;fu&quot;&gt;as.POSIXct&lt;/span&gt;(&lt;span class=&quot;st&quot;&gt;&amp;quot;2007-05-17 09:00:00&amp;quot;&lt;/span&gt;)&lt;span class=&quot;sc&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;as.POSIXct&lt;/span&gt;(&lt;span class=&quot;st&quot;&gt;&amp;quot;2007-05-07 09:00:00&amp;quot;&lt;/span&gt;), &lt;span class=&quot;at&quot;&gt;units=&lt;/span&gt;&lt;span class=&quot;st&quot;&gt;&amp;quot;secs&amp;quot;&lt;/span&gt;)&lt;/span&gt;
&lt;span id=&quot;cb4-2&quot;&gt;&lt;a href=&quot;#cb4-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;[&lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;] &lt;span class=&quot;dv&quot;&gt;864000&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The acceptable &lt;code&gt;units&lt;/code&gt; values are &lt;code&gt;&quot;auto&quot;&lt;/code&gt;,
&lt;code&gt;&quot;secs&quot;&lt;/code&gt;, &lt;code&gt;&quot;mins&quot;&lt;/code&gt;, &lt;code&gt;&quot;hours&quot;&lt;/code&gt;,
&lt;code&gt;&quot;days&quot;&lt;/code&gt;, and &lt;code&gt;&quot;weeks&quot;&lt;/code&gt;.&lt;/p&gt;
</description>
                        <pubDate>Thu, 18 May 2017 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2017-05-18-r-time-interval-to-number</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2017-05-18-r-time-interval-to-number.html</guid>
                </item>
        
                <item>
                        <title>Please help me with these open source Haskell projects</title>
                        <description>&lt;p&gt;Here are some pull requests and issues that have been awaiting my
attention for months or years.&lt;/p&gt;
&lt;p&gt;Sadly, I haven’t found and probably won’t find enough time for them.
So I am asking you for help.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;If you can work on and close at least one of the items below, that
would be awesome.&lt;/p&gt;
&lt;p&gt;Thanks to people who have helped so far:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Alexey Zabelin &lt;a href=&quot;https://github.com/alexeyzab&quot;&gt;@alexeyzab&lt;/a&gt;
— immortal: add wait&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;em&gt;Update (2017-06-14)&lt;/em&gt;. I now have processed most of the PRs
here myself.&lt;/p&gt;
&lt;h2 id=&quot;pull-requests-awaiting-reviews&quot;&gt;Pull requests awaiting
reviews&lt;/h2&gt;
&lt;p&gt;These are pull requests submitted to my projects. For each one, I
describe what needs to be done.&lt;/p&gt;
&lt;h3 id=&quot;ansi-terminal-add-save-restore-report-cursor&quot;&gt;ansi-terminal: add
save, restore, report cursor&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/UnkindPartition/ansi-terminal/pull/18&quot;
class=&quot;uri&quot;&gt;https://github.com/UnkindPartition/ansi-terminal/pull/18&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Needs a review and testing on different platforms.&lt;/p&gt;
&lt;h3
id=&quot;ansi-terminal-compatibility-with-win32-2.5.0.0-and-above&quot;&gt;ansi-terminal:
compatibility with Win32-2.5.0.0 and above&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/UnkindPartition/ansi-terminal/pull/21&quot;
class=&quot;uri&quot;&gt;https://github.com/UnkindPartition/ansi-terminal/pull/21&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Needs review and testing.&lt;/p&gt;
&lt;h3 id=&quot;tasty-build-with-ghcjs&quot;&gt;tasty: build with GHCJS&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/UnkindPartition/tasty/pull/150&quot;
class=&quot;uri&quot;&gt;https://github.com/UnkindPartition/tasty/pull/150&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This one actually has little to do with tasty or ghcjs; it only needs
a PR for the &lt;code&gt;clock&lt;/code&gt; package to fall back to
&lt;code&gt;time&lt;/code&gt;.&lt;/p&gt;
&lt;h3
id=&quot;tasty-make---quickcheck-show-replay-always-show-the-seed-not-just-on-failure&quot;&gt;tasty:
make &lt;code&gt;--quickcheck-show-replay&lt;/code&gt; always show the seed (not
just on failure)&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/UnkindPartition/tasty/pull/143&quot;
class=&quot;uri&quot;&gt;https://github.com/UnkindPartition/tasty/pull/143&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Need to figure out how to fix this without going back to
&lt;code&gt;random&lt;/code&gt; (see &lt;a
href=&quot;https://github.com/UnkindPartition/tasty/issues/141#issuecomment-230166246&quot;&gt;this
comment&lt;/a&gt;).&lt;/p&gt;
&lt;h3
id=&quot;temporary-canonicalized-versions-of-withsystemtempdirectory-and-withtempdirectory&quot;&gt;temporary:
canonicalized versions of &lt;code&gt;withSystemTempDirectory&lt;/code&gt; and
&lt;code&gt;withTempDirectory&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/UnkindPartition/temporary/pull/2&quot;
class=&quot;uri&quot;&gt;https://github.com/UnkindPartition/temporary/pull/2&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Needs another pair of eyes — especially regarding the mysterious
&lt;code&gt;withCanonicalizedSystemTempDirectory&lt;/code&gt;.&lt;/p&gt;
&lt;h3 id=&quot;tasty-add-soft-timeouts&quot;&gt;tasty: add soft timeouts&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/UnkindPartition/tasty/pull/89&quot;
class=&quot;uri&quot;&gt;https://github.com/UnkindPartition/tasty/pull/89&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;When a QuickCheck test runs into a timeout, Tasty does not report the
input values generated by QuickCheck for the interrupted run.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This PR is probably affected by &lt;a
href=&quot;https://github.com/UnkindPartition/tasty/issues/125&quot;&gt;this change
in exception handling&lt;/a&gt; — you’ll need to figure out how exactly and
update the pull request appropriately.&lt;/p&gt;
&lt;h3 id=&quot;immortal-add-wait&quot;&gt;immortal: add wait&lt;/h3&gt;
&lt;p&gt;&lt;em&gt;Done on 2017-05-07 by Alexey Zabelin&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/UnkindPartition/immortal/pull/2&quot;
class=&quot;uri&quot;&gt;https://github.com/UnkindPartition/immortal/pull/2&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;For graceful shutdown, I wait for threads to finish in my servers
main loop. I would like to do the same with Immortal threads.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;What needs to be done:&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;Rebase&lt;/li&gt;
&lt;li&gt;Add a test&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;tasty-golden-add-golden-test-for-text-files&quot;&gt;tasty-golden: add
golden test for text files&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/UnkindPartition/tasty-golden/pull/15&quot;
class=&quot;uri&quot;&gt;https://github.com/UnkindPartition/tasty-golden/pull/15&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I &lt;em&gt;think&lt;/em&gt; the point of this PR is to add an internal diff
implementation, but I am not sure.&lt;/p&gt;
&lt;p&gt;If you understand and like the idea, please update the PR and make a
new case for it; otherwise I’ll probably close it.&lt;/p&gt;
&lt;h3 id=&quot;tasty-silence-a-few-ghc-warnings&quot;&gt;tasty: Silence a few GHC
warnings&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/UnkindPartition/tasty/pull/122&quot;
class=&quot;uri&quot;&gt;https://github.com/UnkindPartition/tasty/pull/122&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Needs rebase and review.&lt;/p&gt;
&lt;h2 id=&quot;issues-that-need-to-be-fixed&quot;&gt;Issues that need to be fixed&lt;/h2&gt;
&lt;p&gt;Here are a couple of issues that I care about and was going to fix
myself, but can’t find the time.&lt;/p&gt;
&lt;h3 id=&quot;stack-no-package-names-in-haddock-index&quot;&gt;stack: no package names
in haddock index&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/commercialhaskell/stack/issues/2886&quot;
class=&quot;uri&quot;&gt;https://github.com/commercialhaskell/stack/issues/2886&lt;/a&gt;&lt;/p&gt;
&lt;h3 id=&quot;xmonad-notifications-pop-up-on-top-of-xscreensaver&quot;&gt;xmonad:
notifications pop up on top of xscreensaver&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/xmonad/xmonad/issues/74&quot;
class=&quot;uri&quot;&gt;https://github.com/xmonad/xmonad/issues/74&lt;/a&gt;&lt;/p&gt;
</description>
                        <pubDate>Thu, 04 May 2017 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2017-05-04-help-haskell-open-source</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2017-05-04-help-haskell-open-source.html</guid>
                </item>
        
                <item>
                        <title>Generic zipWith</title>
                        <description>&lt;p&gt;In response to the &lt;a
href=&quot;/articles/2017-04-23-traverse-with-class-1.0-release&quot;&gt;traverse-with-class
1.0 announcement&lt;/a&gt;, user Gurkenglas &lt;a
href=&quot;https://www.reddit.com/r/haskell/comments/677orv/traversewithclass_10_release/dgovwyg/&quot;&gt;asks&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Can you use something like this to do something like
&lt;code&gt;gzipWith (+) :: (Int, Double) -&amp;gt; (Int, Double) -&amp;gt; (Int, Double)&lt;/code&gt;?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;There are two separate challenges here:&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;How do we traverse two structures in lockstep?&lt;/li&gt;
&lt;li&gt;How do we make sure that the values we are combining are of the same
type?&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Because traverse-with-class implements Michael D. Adams’s generic &lt;a
href=&quot;https://hackage.haskell.org/package/traverse-with-class-1.0.0.0/docs/Data-Generics-Traversable-Zipper.html&quot;&gt;zipper&lt;/a&gt;,
I first thought that it would suffice to traverse the two values
simultaneously. That didn’t quite work out. That zipper is designed to
traverse the structure in all four directions: not just left and right,
but also up and down. Therefore, if we want to traverse an
&lt;code&gt;(Int, Double)&lt;/code&gt; tuple with a &lt;code&gt;Num&lt;/code&gt; constraint, all
possible substructures — including &lt;code&gt;(Int, Double)&lt;/code&gt; itself —
must satisfy that constraint. The way this manifests itself is through
&lt;code&gt;Rec c&lt;/code&gt; constraints, which cannot be satisfied for tuples
without defining extra &lt;code&gt;Num&lt;/code&gt; instances.&lt;/p&gt;
&lt;p&gt;It is possible to design a restricted zipper that would only travel
left and right and will not impose any unnecessary constraints. But
because we need only a simple one-way traversal, we can get away with
something even simpler — a free applicative functor. (Indeed, a free
applicative is a building block in Adams’s zipper.)&lt;/p&gt;
&lt;p&gt;This is simple and beautiful: because a free applicative functor is
an applicative functor, we can &lt;code&gt;gtraverse&lt;/code&gt; with it; and
because a free applicative functor is essentially a heterogeneous list,
we can zip two such things together.&lt;/p&gt;
&lt;p&gt;Another way we could approach this is by using Oleg’s &lt;a
href=&quot;http://okmij.org/ftp/continuations/zipper.html#traversable&quot;&gt;Zipper
from any Traversable&lt;/a&gt;, which is based on the continuation monad. I
haven’t tried it, but I think it should work, too.&lt;/p&gt;
&lt;p&gt;Now we arrive at the second challenge. In traverse-with-class, when
we traverse a heterogeneous value, we observe each field as having an
existential type &lt;code&gt;exists a . c a =&amp;gt; a&lt;/code&gt;. If the type of
&lt;code&gt;(+)&lt;/code&gt; was something like
&lt;code&gt;(Num a1, Num a2) =&amp;gt; a1 -&amp;gt; a2 -&amp;gt; a1&lt;/code&gt; — as it is in
many object-oriented languages — it would be fine. But in Haskell, we
can only add two &lt;code&gt;Num&lt;/code&gt; values if they are of the same
type.&lt;/p&gt;
&lt;p&gt;Packages like &lt;a
href=&quot;https://hackage.haskell.org/package/one-liner&quot;&gt;one-liner&lt;/a&gt; or &lt;a
href=&quot;https://hackage.haskell.org/package/generics-sop&quot;&gt;generics-sop&lt;/a&gt;
use a type-indexed generic representation, so we can assert field-wise
type equality of two structures at compile time. traverse-with-class is
not typed in this sense, so we need to rely on run-time type checks via
&lt;code&gt;Typeable&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The full code for &lt;code&gt;gzipWith&lt;/code&gt; is given below. Note that
relying on &lt;a
href=&quot;http://ro-che.info/articles/2013-03-31-flavours-of-free-applicative-functors&quot;&gt;Ørjan’s
free applicative&lt;/a&gt; has two important consequences:&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;We zip from right to left, so that
&lt;code&gt;gzipWith @Num (+) [1,2,3] [1,2]&lt;/code&gt; evaluates to
&lt;code&gt;[3,5]&lt;/code&gt;, not &lt;code&gt;[2,4]&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;For &lt;code&gt;GTraversable&lt;/code&gt; instances that are right-associated
(e.g. the standard &lt;code&gt;GTraversable&lt;/code&gt; instance for lists), the
complexity is quadratic.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;I believe that both of these issues can be resolved, but I don’t have
the time to spend on this at the moment.&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb1&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb1-1&quot;&gt;&lt;a href=&quot;#cb1-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;{-# OPTIONS_GHC -Wall #-}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-2&quot;&gt;&lt;a href=&quot;#cb1-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;{-# LANGUAGE ScopedTypeVariables, MultiParamTypeClasses, FlexibleInstances,&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-3&quot;&gt;&lt;a href=&quot;#cb1-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;             ConstraintKinds, RankNTypes, AllowAmbiguousTypes, TypeApplications,&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-4&quot;&gt;&lt;a href=&quot;#cb1-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;             UndecidableInstances, GADTs, UndecidableSuperClasses,&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-5&quot;&gt;&lt;a href=&quot;#cb1-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;             FlexibleContexts, TypeOperators #-}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-6&quot;&gt;&lt;a href=&quot;#cb1-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-7&quot;&gt;&lt;a href=&quot;#cb1-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Data.Typeable&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-8&quot;&gt;&lt;a href=&quot;#cb1-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Data.Generics.Traversable&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-9&quot;&gt;&lt;a href=&quot;#cb1-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-10&quot;&gt;&lt;a href=&quot;#cb1-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;co&quot;&gt;-- TypeableAnd c is a synonym for (c a, Typeable a)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-11&quot;&gt;&lt;a href=&quot;#cb1-11&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;class&lt;/span&gt;    (c a, &lt;span class=&quot;dt&quot;&gt;Typeable&lt;/span&gt; a) &lt;span class=&quot;ot&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;TypeableAnd&lt;/span&gt; c a&lt;/span&gt;
&lt;span id=&quot;cb1-12&quot;&gt;&lt;a href=&quot;#cb1-12&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;instance&lt;/span&gt; (c a, &lt;span class=&quot;dt&quot;&gt;Typeable&lt;/span&gt; a) &lt;span class=&quot;ot&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;TypeableAnd&lt;/span&gt; c a&lt;/span&gt;
&lt;span id=&quot;cb1-13&quot;&gt;&lt;a href=&quot;#cb1-13&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-14&quot;&gt;&lt;a href=&quot;#cb1-14&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;co&quot;&gt;-- Ørjan Johansen’s free applicative functor&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-15&quot;&gt;&lt;a href=&quot;#cb1-15&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Free&lt;/span&gt; c a&lt;/span&gt;
&lt;span id=&quot;cb1-16&quot;&gt;&lt;a href=&quot;#cb1-16&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Pure&lt;/span&gt; a&lt;/span&gt;
&lt;span id=&quot;cb1-17&quot;&gt;&lt;a href=&quot;#cb1-17&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;op&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;forall&lt;/span&gt; b&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt; (c b, &lt;span class=&quot;dt&quot;&gt;Typeable&lt;/span&gt; b) &lt;span class=&quot;ot&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Snoc&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;Free&lt;/span&gt; c (b &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; a)) b&lt;/span&gt;
&lt;span id=&quot;cb1-18&quot;&gt;&lt;a href=&quot;#cb1-18&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-19&quot;&gt;&lt;a href=&quot;#cb1-19&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;instance&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Functor&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;Free&lt;/span&gt; c) &lt;span class=&quot;kw&quot;&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-20&quot;&gt;&lt;a href=&quot;#cb1-20&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;fu&quot;&gt;fmap&lt;/span&gt; f (&lt;span class=&quot;dt&quot;&gt;Pure&lt;/span&gt; x) &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Pure&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; f x&lt;/span&gt;
&lt;span id=&quot;cb1-21&quot;&gt;&lt;a href=&quot;#cb1-21&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;fu&quot;&gt;fmap&lt;/span&gt; f (&lt;span class=&quot;dt&quot;&gt;Snoc&lt;/span&gt; lft x) &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Snoc&lt;/span&gt; (&lt;span class=&quot;fu&quot;&gt;fmap&lt;/span&gt; (f &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;) lft) x&lt;/span&gt;
&lt;span id=&quot;cb1-22&quot;&gt;&lt;a href=&quot;#cb1-22&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-23&quot;&gt;&lt;a href=&quot;#cb1-23&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;instance&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Applicative&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;Free&lt;/span&gt; c) &lt;span class=&quot;kw&quot;&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-24&quot;&gt;&lt;a href=&quot;#cb1-24&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;fu&quot;&gt;pure&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Pure&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-25&quot;&gt;&lt;a href=&quot;#cb1-25&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  tx &lt;span class=&quot;op&quot;&gt;&amp;lt;*&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Pure&lt;/span&gt; e &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;fmap&lt;/span&gt; (&lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; e) tx&lt;/span&gt;
&lt;span id=&quot;cb1-26&quot;&gt;&lt;a href=&quot;#cb1-26&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  tx &lt;span class=&quot;op&quot;&gt;&amp;lt;*&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Snoc&lt;/span&gt; ty az &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Snoc&lt;/span&gt; ((&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;) &lt;span class=&quot;op&quot;&gt;&amp;lt;$&amp;gt;&lt;/span&gt; tx &lt;span class=&quot;op&quot;&gt;&amp;lt;*&amp;gt;&lt;/span&gt; ty) az&lt;/span&gt;
&lt;span id=&quot;cb1-27&quot;&gt;&lt;a href=&quot;#cb1-27&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-28&quot;&gt;&lt;a href=&quot;#cb1-28&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;unit ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;TypeableAnd&lt;/span&gt; c b &lt;span class=&quot;ot&quot;&gt;=&amp;gt;&lt;/span&gt; b &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Free&lt;/span&gt; c b&lt;/span&gt;
&lt;span id=&quot;cb1-29&quot;&gt;&lt;a href=&quot;#cb1-29&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;unit &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Snoc&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;Pure&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;id&lt;/span&gt;)&lt;/span&gt;
&lt;span id=&quot;cb1-30&quot;&gt;&lt;a href=&quot;#cb1-30&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-31&quot;&gt;&lt;a href=&quot;#cb1-31&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;toFree ::&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;forall&lt;/span&gt; c a &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;GTraversable&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;TypeableAnd&lt;/span&gt; c) a &lt;span class=&quot;ot&quot;&gt;=&amp;gt;&lt;/span&gt; a &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Free&lt;/span&gt; c a&lt;/span&gt;
&lt;span id=&quot;cb1-32&quot;&gt;&lt;a href=&quot;#cb1-32&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;toFree &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; gtraverse &lt;span class=&quot;op&quot;&gt;@&lt;/span&gt;(&lt;span class=&quot;dt&quot;&gt;TypeableAnd&lt;/span&gt; c) unit&lt;/span&gt;
&lt;span id=&quot;cb1-33&quot;&gt;&lt;a href=&quot;#cb1-33&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-34&quot;&gt;&lt;a href=&quot;#cb1-34&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;fromFree ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Free&lt;/span&gt; c a &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; a&lt;/span&gt;
&lt;span id=&quot;cb1-35&quot;&gt;&lt;a href=&quot;#cb1-35&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;fromFree free &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-36&quot;&gt;&lt;a href=&quot;#cb1-36&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;case&lt;/span&gt; free &lt;span class=&quot;kw&quot;&gt;of&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-37&quot;&gt;&lt;a href=&quot;#cb1-37&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;dt&quot;&gt;Pure&lt;/span&gt; a &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; a&lt;/span&gt;
&lt;span id=&quot;cb1-38&quot;&gt;&lt;a href=&quot;#cb1-38&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;dt&quot;&gt;Snoc&lt;/span&gt; xs x &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; fromFree xs x&lt;/span&gt;
&lt;span id=&quot;cb1-39&quot;&gt;&lt;a href=&quot;#cb1-39&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-40&quot;&gt;&lt;a href=&quot;#cb1-40&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;zipFree ::&lt;/span&gt; (&lt;span class=&quot;kw&quot;&gt;forall&lt;/span&gt; b &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt; c b &lt;span class=&quot;ot&quot;&gt;=&amp;gt;&lt;/span&gt; b &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; b &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; b) &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Free&lt;/span&gt; c a &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Free&lt;/span&gt; c a &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Free&lt;/span&gt; c a&lt;/span&gt;
&lt;span id=&quot;cb1-41&quot;&gt;&lt;a href=&quot;#cb1-41&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;zipFree f free1 free2 &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-42&quot;&gt;&lt;a href=&quot;#cb1-42&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;case&lt;/span&gt; (free1, free2) &lt;span class=&quot;kw&quot;&gt;of&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-43&quot;&gt;&lt;a href=&quot;#cb1-43&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    (&lt;span class=&quot;dt&quot;&gt;Pure&lt;/span&gt; a1, _) &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Pure&lt;/span&gt; a1&lt;/span&gt;
&lt;span id=&quot;cb1-44&quot;&gt;&lt;a href=&quot;#cb1-44&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    (_, &lt;span class=&quot;dt&quot;&gt;Pure&lt;/span&gt; a2) &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Pure&lt;/span&gt; a2&lt;/span&gt;
&lt;span id=&quot;cb1-45&quot;&gt;&lt;a href=&quot;#cb1-45&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    (&lt;span class=&quot;dt&quot;&gt;Snoc&lt;/span&gt; xs1 (&lt;span class=&quot;ot&quot;&gt;x1 ::&lt;/span&gt; b1), &lt;span class=&quot;dt&quot;&gt;Snoc&lt;/span&gt; xs2 (&lt;span class=&quot;ot&quot;&gt;x2 ::&lt;/span&gt; b2)) &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-46&quot;&gt;&lt;a href=&quot;#cb1-46&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;kw&quot;&gt;case&lt;/span&gt; (&lt;span class=&quot;ot&quot;&gt;eqT ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Maybe&lt;/span&gt; (b1 &lt;span class=&quot;op&quot;&gt;:~:&lt;/span&gt; b2)) &lt;span class=&quot;kw&quot;&gt;of&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-47&quot;&gt;&lt;a href=&quot;#cb1-47&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;        &lt;span class=&quot;dt&quot;&gt;Nothing&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;error&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;quot;zipFree: incompatible types&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-48&quot;&gt;&lt;a href=&quot;#cb1-48&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;        &lt;span class=&quot;dt&quot;&gt;Just&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Refl&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Snoc&lt;/span&gt; (zipFree f xs1 xs2) (f x1 x2)&lt;/span&gt;
&lt;span id=&quot;cb1-49&quot;&gt;&lt;a href=&quot;#cb1-49&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-50&quot;&gt;&lt;a href=&quot;#cb1-50&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;gzipWith&lt;/span&gt;
&lt;span id=&quot;cb1-51&quot;&gt;&lt;a href=&quot;#cb1-51&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;  ::&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;forall&lt;/span&gt; c a &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;GTraversable&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;TypeableAnd&lt;/span&gt; c) a&lt;/span&gt;
&lt;span id=&quot;cb1-52&quot;&gt;&lt;a href=&quot;#cb1-52&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;ot&quot;&gt;=&amp;gt;&lt;/span&gt; (&lt;span class=&quot;kw&quot;&gt;forall&lt;/span&gt; b &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt; c b &lt;span class=&quot;ot&quot;&gt;=&amp;gt;&lt;/span&gt; b &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; b &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; b)&lt;/span&gt;
&lt;span id=&quot;cb1-53&quot;&gt;&lt;a href=&quot;#cb1-53&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; a &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; a &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; a&lt;/span&gt;
&lt;span id=&quot;cb1-54&quot;&gt;&lt;a href=&quot;#cb1-54&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;gzipWith f a1 a2 &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; fromFree &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; zipFree f (toFree &lt;span class=&quot;op&quot;&gt;@&lt;/span&gt;c a1) (toFree &lt;span class=&quot;op&quot;&gt;@&lt;/span&gt;c a2)&lt;/span&gt;
&lt;span id=&quot;cb1-55&quot;&gt;&lt;a href=&quot;#cb1-55&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-56&quot;&gt;&lt;a href=&quot;#cb1-56&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;zippedTuple ::&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;Int&lt;/span&gt;, &lt;span class=&quot;dt&quot;&gt;Double&lt;/span&gt;)&lt;/span&gt;
&lt;span id=&quot;cb1-57&quot;&gt;&lt;a href=&quot;#cb1-57&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;zippedTuple &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; gzipWith &lt;span class=&quot;op&quot;&gt;@&lt;/span&gt;&lt;span class=&quot;dt&quot;&gt;Num&lt;/span&gt; (&lt;span class=&quot;op&quot;&gt;+&lt;/span&gt;) (&lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;, &lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;) (&lt;span class=&quot;dv&quot;&gt;3&lt;/span&gt;, &lt;span class=&quot;fu&quot;&gt;pi&lt;/span&gt;)&lt;/span&gt;
&lt;span id=&quot;cb1-58&quot;&gt;&lt;a href=&quot;#cb1-58&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;co&quot;&gt;-- (4,4.141592653589793)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
</description>
                        <pubDate>Tue, 25 Apr 2017 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2017-04-25-generic-zipWith</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2017-04-25-generic-zipWith.html</guid>
                </item>
        
                <item>
                        <title>traverse-with-class 1.0 release</title>
                        <description>&lt;p&gt;I have released the &lt;a
href=&quot;https://hackage.haskell.org/package/traverse-with-class-1.0.0.0&quot;&gt;1.0
version of traverse-with-class&lt;/a&gt;. This library generalizes many
&lt;code&gt;Foldable&lt;/code&gt; and &lt;code&gt;Traversable&lt;/code&gt; functions to
heterogeneous containers such as records.&lt;/p&gt;
&lt;p&gt;For instance, you can apply &lt;code&gt;Show&lt;/code&gt; to all fields and
collect the results:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb1&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb1-1&quot;&gt;&lt;a href=&quot;#cb1-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;{-# LANGUAGE TemplateHaskell, MultiParamTypeClasses, FlexibleInstances,&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-2&quot;&gt;&lt;a href=&quot;#cb1-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;             ConstraintKinds, UndecidableInstances, TypeApplications #-}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-3&quot;&gt;&lt;a href=&quot;#cb1-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-4&quot;&gt;&lt;a href=&quot;#cb1-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Data.Generics.Traversable&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-5&quot;&gt;&lt;a href=&quot;#cb1-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Data.Generics.Traversable.TH&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-6&quot;&gt;&lt;a href=&quot;#cb1-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-7&quot;&gt;&lt;a href=&quot;#cb1-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;User&lt;/span&gt; a &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;User&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-8&quot;&gt;&lt;a href=&quot;#cb1-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt; {&lt;span class=&quot;ot&quot;&gt; name ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;String&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-9&quot;&gt;&lt;a href=&quot;#cb1-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt; ,&lt;span class=&quot;ot&quot;&gt; age  ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Int&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-10&quot;&gt;&lt;a href=&quot;#cb1-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt; ,&lt;span class=&quot;ot&quot;&gt; misc ::&lt;/span&gt; a&lt;/span&gt;
&lt;span id=&quot;cb1-11&quot;&gt;&lt;a href=&quot;#cb1-11&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt; }&lt;/span&gt;
&lt;span id=&quot;cb1-12&quot;&gt;&lt;a href=&quot;#cb1-12&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-13&quot;&gt;&lt;a href=&quot;#cb1-13&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;deriveGTraversable &amp;#39;&lt;span class=&quot;dt&quot;&gt;&amp;#39;User&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-14&quot;&gt;&lt;a href=&quot;#cb1-14&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-15&quot;&gt;&lt;a href=&quot;#cb1-15&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;allFields &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; gfoldMap &lt;span class=&quot;op&quot;&gt;@&lt;/span&gt;&lt;span class=&quot;dt&quot;&gt;Show&lt;/span&gt; (\x &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; [&lt;span class=&quot;fu&quot;&gt;show&lt;/span&gt; x]) &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;User&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;quot;Alice&amp;quot;&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;22&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;True&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-16&quot;&gt;&lt;a href=&quot;#cb1-16&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;co&quot;&gt;-- [&amp;quot;\&amp;quot;Alice\&amp;quot;&amp;quot;,&amp;quot;22&amp;quot;,&amp;quot;True&amp;quot;]&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;You also get a free zipper for your data types.&lt;/p&gt;
&lt;p&gt;The main change in the version 1.0 is that the constraint with which
the traversal is conducted is specified via a &lt;a
href=&quot;https://downloads.haskell.org/~ghc/8.0.2/docs/html/users_guide/glasgow_exts.html#visible-type-application&quot;&gt;visible
type application&lt;/a&gt;. Type applications weren’t available when &lt;a
href=&quot;/articles/2013-03-11-generalizing-gfoldl&quot;&gt;I originally wrote this
library in 2013&lt;/a&gt;, so in that version I used &lt;a
href=&quot;https://downloads.haskell.org/~ghc/8.0.2/docs/html/users_guide/glasgow_exts.html#implicit-parameters&quot;&gt;implicit
parameters&lt;/a&gt; to pass around the annoying proxies.&lt;/p&gt;
&lt;p&gt;Thanks to &lt;a href=&quot;https://github.com/hlian&quot;&gt;Hao Lian&lt;/a&gt; for his
help with this transition.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;Right after I published this blog post, I saw this tweet:&lt;/p&gt;
&lt;blockquote class=&quot;twitter-tweet&quot; data-lang=&quot;en&quot;&gt;
&lt;p lang=&quot;en&quot; dir=&quot;ltr&quot;&gt;
Days since last mailing list discussion of Foldable
tuples:&lt;br&gt;&lt;br&gt;0&lt;br&gt;&lt;br&gt;RESTART THE CLOCK!
&lt;/p&gt;
— Michael Snoyman (&lt;span class=&quot;citation&quot;
data-cites=&quot;snoyberg&quot;&gt;@snoyberg&lt;/span&gt;)
&lt;a href=&quot;https://twitter.com/snoyberg/status/856103284280610816&quot;&gt;April
23, 2017&lt;/a&gt;
&lt;/blockquote&gt;
&lt;script async src=&quot;//platform.twitter.com/widgets.js&quot; charset=&quot;utf-8&quot;&gt;&lt;/script&gt;
&lt;p&gt;Guess what, traverse-with-class provides &lt;em&gt;the sensible&lt;/em&gt;
&lt;code&gt;Foldable&lt;/code&gt;-like instance for tuples:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb2&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb2-1&quot;&gt;&lt;a href=&quot;#cb2-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;{-# LANGUAGE FlexibleInstances, TypeApplications #-}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-2&quot;&gt;&lt;a href=&quot;#cb2-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-3&quot;&gt;&lt;a href=&quot;#cb2-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Data.Generics.Traversable&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-4&quot;&gt;&lt;a href=&quot;#cb2-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-5&quot;&gt;&lt;a href=&quot;#cb2-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;co&quot;&gt;-- U is a trivial constraint satisfied by all types&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-6&quot;&gt;&lt;a href=&quot;#cb2-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;U&lt;/span&gt; a&lt;/span&gt;
&lt;span id=&quot;cb2-7&quot;&gt;&lt;a href=&quot;#cb2-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;instance&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;U&lt;/span&gt; a&lt;/span&gt;
&lt;span id=&quot;cb2-8&quot;&gt;&lt;a href=&quot;#cb2-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-9&quot;&gt;&lt;a href=&quot;#cb2-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;tupleLength &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; gfoldl&amp;#39; &lt;span class=&quot;op&quot;&gt;@&lt;/span&gt;&lt;span class=&quot;dt&quot;&gt;U&lt;/span&gt; (\c _ &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; c &lt;span class=&quot;op&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;) &lt;span class=&quot;dv&quot;&gt;0&lt;/span&gt; (&lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;ot&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;dt&quot;&gt;Int&lt;/span&gt;, &lt;span class=&quot;dt&quot;&gt;True&lt;/span&gt;)&lt;/span&gt;
&lt;span id=&quot;cb2-10&quot;&gt;&lt;a href=&quot;#cb2-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;co&quot;&gt;-- returns 2&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
</description>
                        <pubDate>Sun, 23 Apr 2017 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2017-04-23-traverse-with-class-1.0-release</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2017-04-23-traverse-with-class-1.0-release.html</guid>
                </item>
        
                <item>
                        <title>Disable weird indentation for R in vim</title>
                        <description>&lt;p&gt;By default, vim indents multi-line function calls in R in the
following strange way:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb1&quot;&gt;&lt;pre class=&quot;sourceCode r&quot;&gt;&lt;code class=&quot;sourceCode r&quot;&gt;&lt;span id=&quot;cb1-1&quot;&gt;&lt;a href=&quot;#cb1-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;fu&quot;&gt;some_function&lt;/span&gt;(&lt;/span&gt;
&lt;span id=&quot;cb1-2&quot;&gt;&lt;a href=&quot;#cb1-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;              arg1,&lt;/span&gt;
&lt;span id=&quot;cb1-3&quot;&gt;&lt;a href=&quot;#cb1-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;              arg2,&lt;/span&gt;
&lt;span id=&quot;cb1-4&quot;&gt;&lt;a href=&quot;#cb1-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;              arg3)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;There are two issues with this style:&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;It steals horizontal space, so if some of the arguments are
themselves complex expressions, the lines will quickly become too
long.&lt;/li&gt;
&lt;li&gt;If you rename &lt;code&gt;some_function&lt;/code&gt; or change it to a different
function, the whole block needs to be re-aligned.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;A saner indentation is&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb2&quot;&gt;&lt;pre class=&quot;sourceCode r&quot;&gt;&lt;code class=&quot;sourceCode r&quot;&gt;&lt;span id=&quot;cb2-1&quot;&gt;&lt;a href=&quot;#cb2-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;fu&quot;&gt;some_function&lt;/span&gt;(&lt;/span&gt;
&lt;span id=&quot;cb2-2&quot;&gt;&lt;a href=&quot;#cb2-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  arg1,&lt;/span&gt;
&lt;span id=&quot;cb2-3&quot;&gt;&lt;a href=&quot;#cb2-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  arg2,&lt;/span&gt;
&lt;span id=&quot;cb2-4&quot;&gt;&lt;a href=&quot;#cb2-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  arg3)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;where the indentation amount is small and fixed (say, two
spaces).&lt;/p&gt;
&lt;p&gt;To make vim indent R code this way, add to your
&lt;code&gt;.vimrc&lt;/code&gt;:&lt;/p&gt;
&lt;pre class=&quot;vim&quot;&gt;&lt;code&gt;let r_indent_align_args = 0&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For more information, see &lt;code&gt;:help ft-r-indent&lt;/code&gt;.&lt;/p&gt;
</description>
                        <pubDate>Mon, 03 Apr 2017 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2017-04-03-disable-weird-indentation-rstats-vim</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2017-04-03-disable-weird-indentation-rstats-vim.html</guid>
                </item>
        
                <item>
                        <title>Deploying MathJax</title>
                        <description>&lt;p&gt;&lt;em&gt;Update (2020-03-21)&lt;/em&gt;: the instructions in this post do not
apply for the recently released MathJax-3.0, and I haven’t found a
similar optimization recipe for it.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;MathJax have just &lt;a
href=&quot;https://www.mathjax.org/cdn-shutting-down/&quot;&gt;announced&lt;/a&gt; that
they will shut down their CDN by the end of this month.&lt;/p&gt;
&lt;p&gt;Although they suggest an alternative CDN, I have long wanted to host
a copy of MathJax myself — this has a nice side-effect of being able to
write math-heavy articles while offline (I have a local nginx server
running on my laptop that serves a copy of this site).&lt;/p&gt;
&lt;p&gt;The major obstacle has been the huge size of a default MathJax
installation. It is huge both in terms of the size in bytes (inflating
backups) and in terms of the number of files (slowing down jekyll). In
their blog post, MathJax developers admit this problem and point to the
&lt;a
href=&quot;https://github.com/mathjax/MathJax-docs/wiki/Guide:-reducing-size-of-a-mathjax-installation/1814429ed1e97bfb7675c0fd400804baa9287249&quot;&gt;optimization
guide&lt;/a&gt;. The guide, unfortunately, contains too much text and too few
commands.&lt;/p&gt;
&lt;p&gt;Therefore, I want to document here my process of installing MathJax
2.7.0 — so that I can repeat this in the future, but also in the hope
that this will be useful for others.&lt;/p&gt;
&lt;p&gt;These commands leave only:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;English locale (which is built-in)&lt;/li&gt;
&lt;li&gt;TeX woff fonts&lt;/li&gt;
&lt;li&gt;TeX input&lt;/li&gt;
&lt;li&gt;HTML-CSS output&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;shell&quot;&gt;&lt;code&gt;wget https://github.com/mathjax/MathJax/archive/2.7.0.zip
unzip MathJax-2.7.0.zip
rm MathJax-2.7.0.zip
cd MathJax-2.7.0
rm -rf docs test unpacked .gitignore README-branch.txt README.md bower.json \
  CONTRIBUTING.md LICENSE package.json composer.json .npmignore .travis.yml \
  config/ fonts/HTML-CSS/TeX/png/ localization/ \
  extensions/MathML extensions/asciimath2jax.js extensions/jsMath2jax.js \
  extensions/mml2jax.js extensions/toMathML.js
find fonts/HTML-CSS/ -mindepth 1 -maxdepth 1 ! -name TeX -exec rm -rf {} \+
find fonts -mindepth 3 -maxdepth 3 ! -name woff -exec rm -rf {} +
find jax/input/ -mindepth 1 -maxdepth 1 ! -name TeX -exec rm -rf {} \+
find jax/output/ -mindepth 1 -maxdepth 1 ! -name HTML-CSS -exec rm -rf {} \+
find jax/output/HTML-CSS/fonts -mindepth 1 -maxdepth 1 ! -name TeX -exec rm -rf {} \+&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This brings the installation from 32069 files and 181MiB down to 182
files and 1.7MiB.&lt;/p&gt;
&lt;p&gt;A MathJax config consistent with this installation should look
something like:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb2&quot;&gt;&lt;pre
class=&quot;sourceCode javascript&quot;&gt;&lt;code class=&quot;sourceCode javascript&quot;&gt;&lt;span id=&quot;cb2-1&quot;&gt;&lt;a href=&quot;#cb2-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;MathJax&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;at&quot;&gt;Hub&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;Config&lt;/span&gt;({&lt;/span&gt;
&lt;span id=&quot;cb2-2&quot;&gt;&lt;a href=&quot;#cb2-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;dt&quot;&gt;extensions&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; [&lt;span class=&quot;st&quot;&gt;&amp;quot;tex2jax.js&amp;quot;&lt;/span&gt;]&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-3&quot;&gt;&lt;a href=&quot;#cb2-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;dt&quot;&gt;jax&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; [&lt;span class=&quot;st&quot;&gt;&amp;quot;input/TeX&amp;quot;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;quot;output/HTML-CSS&amp;quot;&lt;/span&gt;]&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-4&quot;&gt;&lt;a href=&quot;#cb2-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;st&quot;&gt;&amp;quot;HTML-CSS&amp;quot;&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; {&lt;/span&gt;
&lt;span id=&quot;cb2-5&quot;&gt;&lt;a href=&quot;#cb2-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;dt&quot;&gt;availableFonts&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; [&lt;span class=&quot;st&quot;&gt;&amp;quot;TeX&amp;quot;&lt;/span&gt;]&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-6&quot;&gt;&lt;a href=&quot;#cb2-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;dt&quot;&gt;imageFont&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;null&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-7&quot;&gt;&lt;a href=&quot;#cb2-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  }&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-8&quot;&gt;&lt;a href=&quot;#cb2-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;dt&quot;&gt;MathMenu&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; {&lt;/span&gt;
&lt;span id=&quot;cb2-9&quot;&gt;&lt;a href=&quot;#cb2-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;   &lt;span class=&quot;dt&quot;&gt;showRenderer&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-10&quot;&gt;&lt;a href=&quot;#cb2-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;   &lt;span class=&quot;dt&quot;&gt;showFontMenu&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-11&quot;&gt;&lt;a href=&quot;#cb2-11&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;   &lt;span class=&quot;dt&quot;&gt;showLocale&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;false&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-12&quot;&gt;&lt;a href=&quot;#cb2-12&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  }&lt;/span&gt;
&lt;span id=&quot;cb2-13&quot;&gt;&lt;a href=&quot;#cb2-13&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;})&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
</description>
                        <pubDate>Sun, 02 Apr 2017 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2017-04-02-deploying-mathjax</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2017-04-02-deploying-mathjax.html</guid>
                </item>
        
                <item>
                        <title>Increase the open files limit on Linux</title>
                        <description>&lt;p&gt;Each process on Linux has &lt;a
href=&quot;https://linux.die.net/man/2/setrlimit&quot;&gt;several limits&lt;/a&gt;
associated with it, such as the maximum number of files it can open
simultaneously. You can find out your current open files limit by
running&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb1&quot;&gt;&lt;pre
class=&quot;sourceCode bash&quot;&gt;&lt;code class=&quot;sourceCode bash&quot;&gt;&lt;span id=&quot;cb1-1&quot;&gt;&lt;a href=&quot;#cb1-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;bu&quot;&gt;ulimit&lt;/span&gt; &lt;span class=&quot;at&quot;&gt;-Sn&lt;/span&gt; &lt;span class=&quot;co&quot;&gt;# soft limit; can be raised up to the hard limit&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-2&quot;&gt;&lt;a href=&quot;#cb1-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;bu&quot;&gt;ulimit&lt;/span&gt; &lt;span class=&quot;at&quot;&gt;-Hn&lt;/span&gt; &lt;span class=&quot;co&quot;&gt;# hard limit&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;To see all limits, run&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb2&quot;&gt;&lt;pre
class=&quot;sourceCode bash&quot;&gt;&lt;code class=&quot;sourceCode bash&quot;&gt;&lt;span id=&quot;cb2-1&quot;&gt;&lt;a href=&quot;#cb2-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;bu&quot;&gt;ulimit&lt;/span&gt; &lt;span class=&quot;at&quot;&gt;-Sa&lt;/span&gt; &lt;span class=&quot;co&quot;&gt;# soft limits&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-2&quot;&gt;&lt;a href=&quot;#cb2-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;bu&quot;&gt;ulimit&lt;/span&gt; &lt;span class=&quot;at&quot;&gt;-Ha&lt;/span&gt; &lt;span class=&quot;co&quot;&gt;# hard limits&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The way you can adjust these limits depends on the particular Linux
system (e.g. whether it is systemd-based, and possibly even on the
version of systemd) and on the way you logged into the system (via
console, gdm, lightdm etc.)&lt;/p&gt;
&lt;p&gt;Here I describe a few steps that can help you to increase the open
files limit. It’s hard to predict which steps will be relevant, but if
you follow all of them, there’s a good chance you will succeed.&lt;/p&gt;
&lt;p&gt;Similar instructions should work for other limits, too.&lt;/p&gt;
&lt;h2 id=&quot;pam&quot;&gt;PAM&lt;/h2&gt;
&lt;p&gt;Edit the file &lt;code&gt;/etc/security/limits.conf&lt;/code&gt; and add the
following line:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;* - nofile 20000&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;where 20000 is the desired limit. The &lt;code&gt;*&lt;/code&gt; means all users,
and the &lt;code&gt;-&lt;/code&gt; means set both soft and hard limits. See &lt;a
href=&quot;https://linux.die.net/man/5/limits.conf&quot;&gt;limits.conf(5)&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;You may want to replace the &lt;code&gt;*&lt;/code&gt; with a specific user name.
Moreover, to change the limits for &lt;code&gt;root&lt;/code&gt;, you &lt;a
href=&quot;https://bugs.launchpad.net/ubuntu/+source/pam/+bug/65244&quot;&gt;may
&lt;em&gt;need&lt;/em&gt; to write &lt;code&gt;root&lt;/code&gt; instead of
&lt;code&gt;*&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Check that there are no conflicting declarations under
&lt;code&gt;/etc/security/limits.d/*.conf&lt;/code&gt;, as those files take
precedence.&lt;/p&gt;
&lt;p&gt;Next, to ensure that these settings are applied, locate the file
under &lt;code&gt;/etc/pam.d&lt;/code&gt; that corresponds to your login method
(&lt;code&gt;/etc/pam.d/login&lt;/code&gt; for console,
&lt;code&gt;/etc/pam.d/lightdm&lt;/code&gt; for lightdm and so on) and add the
following line unless it is already there:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;session required pam_limits.so&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For the changes to take effect, it should be sufficient to
re-login.&lt;/p&gt;
&lt;p&gt;On Fedora 25, the PAM settings alone seemed to work for the console
login but not for the lightdm login.&lt;/p&gt;
&lt;h2 id=&quot;systemd&quot;&gt;systemd&lt;/h2&gt;
&lt;p&gt;If you are on a systemd-based system, try editing &lt;em&gt;both&lt;/em&gt;
&lt;code&gt;/etc/systemd/system.conf&lt;/code&gt; and
&lt;code&gt;/etc/systemd/user.conf&lt;/code&gt; and adding the following line under
the &lt;code&gt;[Manager]&lt;/code&gt; section (see &lt;a
href=&quot;https://www.freedesktop.org/software/systemd/man/systemd-system.conf.html&quot;&gt;systemd-system.conf(5)&lt;/a&gt;):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;DefaultLimitNOFILE=20000&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then reboot the system.&lt;/p&gt;
&lt;p&gt;I found out about this setting from &lt;a
href=&quot;https://bugs.launchpad.net/ubuntu/+source/lightdm/+bug/1627769/comments/5&quot;&gt;a
comment by Ewan Leith&lt;/a&gt;, but changing &lt;code&gt;user.conf&lt;/code&gt; alone
didn’t work for me; I had to change both &lt;code&gt;user.conf&lt;/code&gt; and
&lt;code&gt;system.conf&lt;/code&gt;.&lt;/p&gt;
</description>
                        <pubDate>Sun, 26 Mar 2017 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2017-03-26-increase-open-files-limit</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2017-03-26-increase-open-files-limit.html</guid>
                </item>
        
                <item>
                        <title>Haskell without GMP</title>
                        <description>&lt;p&gt;When you compile a Haskell program with &lt;a
href=&quot;https://www.haskell.org/ghc/&quot;&gt;GHC&lt;/a&gt;, by default your program is
linked against the &lt;a href=&quot;https://gmplib.org/&quot;&gt;GMP&lt;/a&gt; (GNU Multiple
Precision Arithmetic) library. GHC uses GMP to implement Haskell’s
arbitrary-precision &lt;code&gt;Integer&lt;/code&gt; type.&lt;/p&gt;
&lt;p&gt;Because GMP is distributed under the L/GPL licenses, this presents a
problem if you want to &lt;a
href=&quot;/articles/2015-10-26-static-linking-ghc&quot;&gt;link the executable
statically&lt;/a&gt; and distribute it without the &lt;a
href=&quot;https://www.gnu.org/licenses/gpl-faq.html#LGPLStaticVsDynamic&quot;&gt;implications
of LGPL&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Here I’ll show how to compile a Haskell program without GMP. The
process consists of two steps:&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;Install a GHC compiled with integer-simple instead of GMP. You may
need to compile such a GHC yourself.&lt;/li&gt;
&lt;li&gt;Make sure your dependencies do not use GMP.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;These instructions are geared towards &lt;a
href=&quot;https://docs.haskellstack.org/en/stable/README/&quot;&gt;stack&lt;/a&gt;, but it
should be clear how to adapt them to other workflows.&lt;/p&gt;
&lt;h2 id=&quot;install-ghc-with-integer-simple&quot;&gt;Install GHC with
integer-simple&lt;/h2&gt;
&lt;p&gt;&lt;a
href=&quot;https://hackage.haskell.org/package/integer-simple&quot;&gt;integer-simple&lt;/a&gt;
is a pure Haskell implementation of the subset of GMP functionality.&lt;/p&gt;
&lt;p&gt;Because the &lt;code&gt;Integer&lt;/code&gt; type is provided by the
&lt;code&gt;base&lt;/code&gt; library, and the &lt;code&gt;base&lt;/code&gt; library is compiled
at the same time as GHC itself, we need a different build of GHC to
support integer-simple — although &lt;a
href=&quot;https://github.com/commercialhaskell/stack/issues/399#issuecomment-115530839&quot;&gt;that
may change at some point&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;At the time of writing, FP Complete distributes integer-simple builds
for several recent versions of GHC, but only for Windows. To check, look
at the current version of &lt;a
href=&quot;https://github.com/fpco/stackage-content/blob/master/stack/stack-setup-2.yaml&quot;&gt;stack-setup-2.yaml&lt;/a&gt;
and search for “integersimple”.&lt;/p&gt;
&lt;p&gt;Thus, on Windows you can say&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;stack setup --ghc-variant=integersimple 8.0.2&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;and it will download and install the GHC 8.0.2 based on
integer-simple.&lt;/p&gt;
&lt;p&gt;If you are inside a stack project, add&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ghc-variant: integersimple&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;to &lt;code&gt;stack.yaml&lt;/code&gt; so that stack knows which compiler flavor
to use. Also, in this case you don’t need to give
&lt;code&gt;stack setup&lt;/code&gt; the GHC version or &lt;code&gt;--ghc-variant&lt;/code&gt;;
these will be taken from &lt;code&gt;stack.yaml&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;If there is no precompiled integer-simple GHC for your platform or
desired GHC version, you’ll have to build it yourself as I describe
below.&lt;/p&gt;
&lt;h2 id=&quot;compile-ghc-with-integer-simple&quot;&gt;Compile GHC with
integer-simple&lt;/h2&gt;
&lt;p&gt;These instructions were tested with GHC 8.0.2 on Linux and macOS.&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;&lt;p&gt;Check the &lt;a
href=&quot;https://ghc.haskell.org/trac/ghc/wiki/Building/Preparation&quot;&gt;system
requirements&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a
href=&quot;https://ghc.haskell.org/trac/ghc/wiki/Building/GettingTheSources&quot;&gt;Get
the GHC source&lt;/a&gt; by either cloning the git repo or downloading the
source tarball.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Save the template &lt;code&gt;mk/build.mk.sample&lt;/code&gt; as
&lt;code&gt;mk/build.mk&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cp mk/build.mk.sample mk/build.mk&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, add the following line somewhere in
&lt;code&gt;mk/build.mk&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;INTEGER_LIBRARY=integer-simple&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;While editing that file, also choose the build profile by
uncommenting one of the &lt;code&gt;BuildFlavour =&lt;/code&gt; lines.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;To test the process, use &lt;code&gt;BuildFlavour = quick&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Once you are happy with the result, run &lt;code&gt;make distclean&lt;/code&gt;
and rebuild with &lt;code&gt;BuildFlavour = perf&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Another option I found useful to set in &lt;code&gt;mk/build.mk&lt;/code&gt;
is&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;BUILD_SPHINX_PDF=NO&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Otherwise, I get errors because I don’t have various exotic TeX
packages installed.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Follow the &lt;a
href=&quot;https://ghc.haskell.org/trac/ghc/wiki/Building/QuickStart&quot;&gt;standard
build instructions&lt;/a&gt;, except the final &lt;code&gt;make install&lt;/code&gt;
command.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Run &lt;code&gt;make binary-dist&lt;/code&gt; to generate the release
tarball.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Download the current &lt;a
href=&quot;https://github.com/fpco/stackage-content/blob/master/stack/stack-setup-2.yaml&quot;&gt;stack-setup-2.yaml&lt;/a&gt;
and add a record for your release, such as&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb6&quot;&gt;&lt;pre
class=&quot;sourceCode yaml&quot;&gt;&lt;code class=&quot;sourceCode yaml&quot;&gt;&lt;span id=&quot;cb6-1&quot;&gt;&lt;a href=&quot;#cb6-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;fu&quot;&gt;linux64-integersimple-tinfo6&lt;/span&gt;&lt;span class=&quot;kw&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-2&quot;&gt;&lt;a href=&quot;#cb6-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;at&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;8.0.2&lt;/span&gt;&lt;span class=&quot;kw&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-3&quot;&gt;&lt;a href=&quot;#cb6-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;at&quot;&gt;        &lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;kw&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;at&quot;&gt; &lt;/span&gt;&lt;span class=&quot;st&quot;&gt;&amp;quot;/home/user/ghc/ghc-8.0.2-x86_64-unknown-linux.tar.xz&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-4&quot;&gt;&lt;a href=&quot;#cb6-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;at&quot;&gt;        &lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;content-length&lt;/span&gt;&lt;span class=&quot;kw&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;at&quot;&gt; &lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;114017964&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-5&quot;&gt;&lt;a href=&quot;#cb6-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;at&quot;&gt;        &lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;sha1&lt;/span&gt;&lt;span class=&quot;kw&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;at&quot;&gt; ad38970c4431d44fef38c4696847ba491ef24332&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Now you can follow the instructions from the previous section, except
replace the &lt;code&gt;stack-setup-2.yaml&lt;/code&gt; url with the path or url of
your own &lt;code&gt;stack-setup-2.yaml&lt;/code&gt; file.&lt;/p&gt;
&lt;h2 id=&quot;make-sure-your-dependencies-do-not-use-gmp&quot;&gt;Make sure your
dependencies do not use GMP&lt;/h2&gt;
&lt;p&gt;Some packages depend on GMP through the &lt;a
href=&quot;https://hackage.haskell.org/package/integer-gmp&quot;&gt;integer-gmp&lt;/a&gt;
package.&lt;/p&gt;
&lt;p&gt;Fortunately, such packages usually have a Cabal flag to remove this
dependency or replace it with integer-simple. The flag itself is usually
called &lt;code&gt;integer-gmp&lt;/code&gt; or &lt;code&gt;integer-simple&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;There are different ways to set these flags. With stack, you can
declare the flags in &lt;code&gt;stack.yaml&lt;/code&gt; as follows:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb7&quot;&gt;&lt;pre
class=&quot;sourceCode yaml&quot;&gt;&lt;code class=&quot;sourceCode yaml&quot;&gt;&lt;span id=&quot;cb7-1&quot;&gt;&lt;a href=&quot;#cb7-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;fu&quot;&gt;extra-deps&lt;/span&gt;&lt;span class=&quot;kw&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb7-2&quot;&gt;&lt;a href=&quot;#cb7-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;at&quot;&gt; text-1.2.2.1&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb7-3&quot;&gt;&lt;a href=&quot;#cb7-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;at&quot;&gt; hashable-1.2.5.0&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb7-4&quot;&gt;&lt;a href=&quot;#cb7-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;at&quot;&gt; scientific-0.3.4.10&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb7-5&quot;&gt;&lt;a href=&quot;#cb7-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;at&quot;&gt; integer-logarithms-1.0.1&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb7-6&quot;&gt;&lt;a href=&quot;#cb7-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;at&quot;&gt; cryptonite-0.22&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb7-7&quot;&gt;&lt;a href=&quot;#cb7-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb7-8&quot;&gt;&lt;a href=&quot;#cb7-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;fu&quot;&gt;flags&lt;/span&gt;&lt;span class=&quot;kw&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb7-9&quot;&gt;&lt;a href=&quot;#cb7-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;at&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;kw&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb7-10&quot;&gt;&lt;a href=&quot;#cb7-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;at&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;integer-simple&lt;/span&gt;&lt;span class=&quot;kw&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;at&quot;&gt; &lt;/span&gt;&lt;span class=&quot;ch&quot;&gt;true&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb7-11&quot;&gt;&lt;a href=&quot;#cb7-11&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;at&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;hashable&lt;/span&gt;&lt;span class=&quot;kw&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb7-12&quot;&gt;&lt;a href=&quot;#cb7-12&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;at&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;integer-gmp&lt;/span&gt;&lt;span class=&quot;kw&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;at&quot;&gt; &lt;/span&gt;&lt;span class=&quot;ch&quot;&gt;false&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb7-13&quot;&gt;&lt;a href=&quot;#cb7-13&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;at&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;scientific&lt;/span&gt;&lt;span class=&quot;kw&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb7-14&quot;&gt;&lt;a href=&quot;#cb7-14&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;at&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;integer-simple&lt;/span&gt;&lt;span class=&quot;kw&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;at&quot;&gt; &lt;/span&gt;&lt;span class=&quot;ch&quot;&gt;true&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb7-15&quot;&gt;&lt;a href=&quot;#cb7-15&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;at&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;integer-logarithms&lt;/span&gt;&lt;span class=&quot;kw&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb7-16&quot;&gt;&lt;a href=&quot;#cb7-16&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;at&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;integer-gmp&lt;/span&gt;&lt;span class=&quot;kw&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;at&quot;&gt; &lt;/span&gt;&lt;span class=&quot;ch&quot;&gt;false&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb7-17&quot;&gt;&lt;a href=&quot;#cb7-17&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;at&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;cryptonite&lt;/span&gt;&lt;span class=&quot;kw&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb7-18&quot;&gt;&lt;a href=&quot;#cb7-18&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;at&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;integer-gmp&lt;/span&gt;&lt;span class=&quot;kw&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;at&quot;&gt; &lt;/span&gt;&lt;span class=&quot;ch&quot;&gt;false&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The above YAML snippet can be easily turned into a &lt;a
href=&quot;https://docs.haskellstack.org/en/stable/custom_snapshot/#specifying-flags&quot;&gt;custom
snapshot&lt;/a&gt; and shared among multiple stack projects if needed.&lt;/p&gt;
&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/commercialhaskell/stack/issues/399&quot;&gt;LGPL
licensing restrictions on Windows because of integer-gmp&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://stackoverflow.com/q/42691533/110081&quot;&gt;How to use
different ghc builds with stack?&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
</description>
                        <pubDate>Fri, 10 Mar 2017 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2017-03-10-haskell-without-gmp</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2017-03-10-haskell-without-gmp.html</guid>
                </item>
        
                <item>
                        <title>Group data by month in R</title>
                        <description>&lt;p&gt;I often analyze time series data in R — things like daily expenses or
webserver statistics. And just as often I want to aggregate the data by
month to see longer-term patterns.&lt;/p&gt;
&lt;p&gt;Doing this in base R is a bit awkward, and the internet is littered
with working but terrible solutions using &lt;code&gt;strftime&lt;/code&gt; or
similar date-to-string conversions.&lt;/p&gt;
&lt;p&gt;The real gem is the function &lt;code&gt;floor_date&lt;/code&gt; from the
&lt;code&gt;lubridate&lt;/code&gt; package. I found out about it from &lt;a
href=&quot;http://stackoverflow.com/a/6082768/110081&quot;&gt;this old StackOverflow
answer&lt;/a&gt; by Hadley Wickham. As the name implies, it can be used to
round each date down to the month boundary, so that dates in the same
month are rounded down to the same date.&lt;/p&gt;
&lt;p&gt;Let’s look at an example.&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb1&quot;&gt;&lt;pre class=&quot;sourceCode r&quot;&gt;&lt;code class=&quot;sourceCode r&quot;&gt;&lt;span id=&quot;cb1-1&quot;&gt;&lt;a href=&quot;#cb1-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;fu&quot;&gt;library&lt;/span&gt;(dplyr)&lt;/span&gt;
&lt;span id=&quot;cb1-2&quot;&gt;&lt;a href=&quot;#cb1-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;fu&quot;&gt;library&lt;/span&gt;(lubridate)&lt;/span&gt;
&lt;span id=&quot;cb1-3&quot;&gt;&lt;a href=&quot;#cb1-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;fu&quot;&gt;set.seed&lt;/span&gt;(&lt;span class=&quot;dv&quot;&gt;2017&lt;/span&gt;)&lt;/span&gt;
&lt;span id=&quot;cb1-4&quot;&gt;&lt;a href=&quot;#cb1-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;fu&quot;&gt;options&lt;/span&gt;(&lt;span class=&quot;at&quot;&gt;digits=&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;4&lt;/span&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Say these are your daily expenses for 2016:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb2&quot;&gt;&lt;pre class=&quot;sourceCode r&quot;&gt;&lt;code class=&quot;sourceCode r&quot;&gt;&lt;span id=&quot;cb2-1&quot;&gt;&lt;a href=&quot;#cb2-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;(expenses &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;data_frame&lt;/span&gt;(&lt;/span&gt;
&lt;span id=&quot;cb2-2&quot;&gt;&lt;a href=&quot;#cb2-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;at&quot;&gt;date=&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;seq&lt;/span&gt;(&lt;span class=&quot;fu&quot;&gt;as.Date&lt;/span&gt;(&lt;span class=&quot;st&quot;&gt;&amp;quot;2016-01-01&amp;quot;&lt;/span&gt;), &lt;span class=&quot;fu&quot;&gt;as.Date&lt;/span&gt;(&lt;span class=&quot;st&quot;&gt;&amp;quot;2016-12-31&amp;quot;&lt;/span&gt;), &lt;span class=&quot;at&quot;&gt;by=&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;),&lt;/span&gt;
&lt;span id=&quot;cb2-3&quot;&gt;&lt;a href=&quot;#cb2-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;at&quot;&gt;amount=&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;rgamma&lt;/span&gt;(&lt;span class=&quot;fu&quot;&gt;length&lt;/span&gt;(date), &lt;span class=&quot;at&quot;&gt;shape =&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;2&lt;/span&gt;, &lt;span class=&quot;at&quot;&gt;scale =&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;20&lt;/span&gt;)))&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;pre&gt;&lt;code&gt;## # A tibble: 366 × 2
##          date amount
##        &amp;lt;date&amp;gt;  &amp;lt;dbl&amp;gt;
## 1  2016-01-01  75.42
## 2  2016-01-02  28.14
## 3  2016-01-03  51.12
## 4  2016-01-04  26.12
## 5  2016-01-05  42.09
## 6  2016-01-06  40.99
## 7  2016-01-07  45.59
## 8  2016-01-08  57.55
## 9  2016-01-09  22.98
## 10 2016-01-10  14.50
## # ... with 356 more rows&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then you can summarize them by month like this:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb4&quot;&gt;&lt;pre class=&quot;sourceCode r&quot;&gt;&lt;code class=&quot;sourceCode r&quot;&gt;&lt;span id=&quot;cb4-1&quot;&gt;&lt;a href=&quot;#cb4-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;expenses &lt;span class=&quot;sc&quot;&gt;%&amp;gt;%&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;group_by&lt;/span&gt;(&lt;span class=&quot;at&quot;&gt;month=&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;floor_date&lt;/span&gt;(date, &lt;span class=&quot;st&quot;&gt;&amp;quot;month&amp;quot;&lt;/span&gt;)) &lt;span class=&quot;sc&quot;&gt;%&amp;gt;%&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-2&quot;&gt;&lt;a href=&quot;#cb4-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;   &lt;span class=&quot;fu&quot;&gt;summarize&lt;/span&gt;(&lt;span class=&quot;at&quot;&gt;amount=&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;sum&lt;/span&gt;(amount))&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;pre&gt;&lt;code&gt;## # A tibble: 12 × 2
##         month amount
##        &amp;lt;date&amp;gt;  &amp;lt;dbl&amp;gt;
## 1  2016-01-01 1200.9
## 2  2016-02-01 1002.9
## 3  2016-03-01 1237.6
## 4  2016-04-01 1120.8
## 5  2016-05-01 1276.6
## 6  2016-06-01 1404.6
## 7  2016-07-01  972.6
## 8  2016-08-01 1245.7
## 9  2016-09-01 1020.2
## 10 2016-10-01  986.2
## 11 2016-11-01 1106.3
## 12 2016-12-01 1235.2&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;floor_date&lt;/code&gt; lets you round dates to various time periods
from seconds to years and also multiples of these periods, e.g.&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb6&quot;&gt;&lt;pre class=&quot;sourceCode r&quot;&gt;&lt;code class=&quot;sourceCode r&quot;&gt;&lt;span id=&quot;cb6-1&quot;&gt;&lt;a href=&quot;#cb6-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;expenses &lt;span class=&quot;sc&quot;&gt;%&amp;gt;%&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;group_by&lt;/span&gt;(&lt;span class=&quot;at&quot;&gt;month=&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;floor_date&lt;/span&gt;(date, &lt;span class=&quot;st&quot;&gt;&amp;quot;14 days&amp;quot;&lt;/span&gt;)) &lt;span class=&quot;sc&quot;&gt;%&amp;gt;%&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-2&quot;&gt;&lt;a href=&quot;#cb6-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;   &lt;span class=&quot;fu&quot;&gt;summarize&lt;/span&gt;(&lt;span class=&quot;at&quot;&gt;amount=&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;sum&lt;/span&gt;(amount))&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;pre&gt;&lt;code&gt;## # A tibble: 36 × 2
##         month amount
##        &amp;lt;date&amp;gt;  &amp;lt;dbl&amp;gt;
## 1  2016-01-01  550.0
## 2  2016-01-15  462.1
## 3  2016-01-29  188.8
## 4  2016-02-01  568.2
## 5  2016-02-15  335.1
## 6  2016-02-29   99.6
## 7  2016-03-01  675.7
## 8  2016-03-15  459.8
## 9  2016-03-29  102.2
## 10 2016-04-01  458.3
## # ... with 26 more rows&lt;/code&gt;&lt;/pre&gt;
</description>
                        <pubDate>Wed, 22 Feb 2017 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2017-02-22-group_by_month_r</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2017-02-22-group_by_month_r.html</guid>
                </item>
        
                <item>
                        <title>Theory behind RSEM</title>
                        <description>&lt;p&gt;In this article, I will walk through and try to explain a 2009 paper
&lt;a
href=&quot;https://academic.oup.com/bioinformatics/article-lookup/doi/10.1093/bioinformatics/btp692&quot;&gt;RNA-Seq
gene expression estimation with read mapping uncertainty&lt;/a&gt; by Bo Li,
Victor Ruotti, Ron M. Stewart, James A. Thomson, and Colin N. Dewey.&lt;/p&gt;
&lt;p&gt;I will also occasionally refer to a 2011 paper by Bo Li and Colin N.
Dewey, &lt;a
href=&quot;http://bmcbioinformatics.biomedcentral.com/articles/10.1186/1471-2105-12-323&quot;&gt;RSEM:
accurate transcript quantification from RNA-Seq data with or without a
reference genome&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Together, the two papers explain the theory behind the software
package for estimating gene and isoform expression levels &lt;a
href=&quot;https://deweylab.github.io/RSEM/&quot;&gt;RSEM&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;/h2&gt;
&lt;p&gt;An RNA-Seq experiment proceeds roughly as follows:&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;A class of RNA molecules (e.g., mRNA) is extracted from a biological
sample.&lt;/li&gt;
&lt;li&gt;The molecules are fragmented. The size of RNA fragments is in the
hundreds of nucleotides.&lt;/li&gt;
&lt;li&gt;A random sample of the RNA fragments is sequenced. The obtained
sequences are called &lt;em&gt;reads&lt;/em&gt; and usually have a fixed length from
50 to 250 nucleotides.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Typically (but &lt;a
href=&quot;http://www.nature.com/nature/journal/v461/n7265/full/nature08390.html&quot;&gt;not
always&lt;/a&gt;), the RNA is reverse-transcribed to DNA either before or
after fragmentation, and it is the DNA that gets sequenced, but that’s
irrelevant for us here.&lt;/p&gt;
&lt;p&gt;The goal of the RNA-Seq data analysis is, given the reads and a list
of known gene isoforms (all possible RNA sequences), estimate the
relative number of RNA molecules (transcripts) of each isoform in the
original biological sample.&lt;/p&gt;
&lt;p&gt;So, for instance, given two isoforms&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(isoform 1) AAAAAAAAAAA
(isoform 2) UUUUUUUUUUU&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;and three reads&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(read 1)    AAAAAAA
(read 2)    UUUUUUU
(read 3)    AAAAAAA&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;we might estimate that rougly &lt;span
class=&quot;math inline&quot;&gt;\(2/3\)&lt;/span&gt; of all transcripts in the biological
sample were from isoform 1 and &lt;span class=&quot;math inline&quot;&gt;\(1/3\)&lt;/span&gt;
were from isoform 2.&lt;/p&gt;
&lt;p&gt;A simple estimation method is to count the reads that align to each
isoform and then &lt;a href=&quot;2016-11-28-rna-seq-normalization&quot;&gt;adjust the
counts for the number of reads and isoform sizes&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;However, not all reads align to a single isoform. Isoforms of the
same gene are highly similar: they all are built from the same small set
of segments (&lt;em&gt;exons&lt;/em&gt;). Different genes may also be highly
similar. More than a half of the reads in any given experiment may map
to more than one isoform. Such reads are called &lt;em&gt;multireads&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;We could just ignore multireads and consider only the reads that
unambiguously map to one isoform. One problem with this is discarding a
lot of useful data. But more importantly, without a careful adjustment,
discarding multireads introduces a bias: we will underestimate the
abundance of genes that have many active isoforms or other similar
genes, as these genes are more likely to produce multireads.&lt;/p&gt;
&lt;p&gt;The paper describes a probabilistic model and a computational method
to estimate isoform abundances based on all available reads, including
multireads.&lt;/p&gt;
&lt;h2 id=&quot;simplifications&quot;&gt;Simplifications&lt;/h2&gt;
&lt;p&gt;As in the original paper, we will assume single-end reads and ignore
quality scores. Besides, we will make two addional assumptions compared
to the paper:&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;The protocol is strand-specific; that is, we will assume the
orientation of the reads is known just so that we have fewer variables
to model.&lt;/li&gt;
&lt;li&gt;All reads come from a known list of isoforms. Therefore, we will not
consider the “noise” isoform (&lt;span class=&quot;math inline&quot;&gt;\(i=0\)&lt;/span&gt;
in the paper).&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;notation-and-variables&quot;&gt;Notation and variables&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;span class=&quot;math inline&quot;&gt;\(N\)&lt;/span&gt; is the total number of
reads (called &lt;em&gt;library size&lt;/em&gt;); &lt;span
class=&quot;math inline&quot;&gt;\(n=1,\ldots,N\)&lt;/span&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;span class=&quot;math inline&quot;&gt;\(M\)&lt;/span&gt; is the number of known
isoforms; &lt;span class=&quot;math inline&quot;&gt;\(i=1,\ldots,M\)&lt;/span&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;span class=&quot;math inline&quot;&gt;\(L\)&lt;/span&gt; is the read
length.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;span class=&quot;math inline&quot;&gt;\(l_i\)&lt;/span&gt; is the length of isoform
&lt;span class=&quot;math inline&quot;&gt;\(i\)&lt;/span&gt;; &lt;span
class=&quot;math inline&quot;&gt;\(j=1,\ldots,l_i\)&lt;/span&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;span class=&quot;math inline&quot;&gt;\(R_n\)&lt;/span&gt; is the sequence of read
&lt;span class=&quot;math inline&quot;&gt;\(n\)&lt;/span&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Read &lt;span class=&quot;math inline&quot;&gt;\(n\)&lt;/span&gt; is assumed to start
at a position &lt;span class=&quot;math inline&quot;&gt;\(S_n\in[1,l_i]\)&lt;/span&gt; in the
isoform &lt;span class=&quot;math inline&quot;&gt;\(G_n=i\in[1,M]\)&lt;/span&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;span class=&quot;math inline&quot;&gt;\(\tau_i\)&lt;/span&gt; is the fraction of
transcripts that belong to isoform &lt;span
class=&quot;math inline&quot;&gt;\(i\)&lt;/span&gt; out of all transcripts in the sample.
When multiplied by million, it is the &lt;a
href=&quot;2016-11-28-rna-seq-normalization&quot;&gt;transcripts per million
(TPM)&lt;/a&gt; measure.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;span class=&quot;math inline&quot;&gt;\(\theta_i\)&lt;/span&gt; is the prior
probability that any single read is derived from isoform &lt;span
class=&quot;math inline&quot;&gt;\(i\)&lt;/span&gt;: &lt;span
class=&quot;math inline&quot;&gt;\(\theta_i=p(G_n=i)\)&lt;/span&gt;. Because longer
isoforms are expected to produce proportionally more fragments and
reads, the relationship between &lt;span
class=&quot;math inline&quot;&gt;\(\tau_i\)&lt;/span&gt; and &lt;span
class=&quot;math inline&quot;&gt;\(\theta_i\)&lt;/span&gt; is: &lt;span
class=&quot;math display&quot;&gt;\[\theta_i=\frac{\tau_i\cdot
l_i}{\sum_{k=1}^{M}\tau_{k}\cdot l_{k}},\]&lt;/span&gt; &lt;span
class=&quot;math display&quot;&gt;\[\tau_i=\frac{\theta_i/l_i}{\sum_{k=1}^{M}\theta_{k}/l_{k}}.\]&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;In other words, &lt;span class=&quot;math inline&quot;&gt;\(\theta_i\propto
\tau_i\cdot l_i\)&lt;/span&gt; subject to &lt;span class=&quot;math inline&quot;&gt;\(\sum_i
\theta_i = \sum_i \tau_i = 1\)&lt;/span&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The symbol &lt;span class=&quot;math inline&quot;&gt;\(\propto\)&lt;/span&gt; used
above means “proportional to”. The formula &lt;span
class=&quot;math inline&quot;&gt;\(\theta_i\propto \tau_i\cdot l_i\)&lt;/span&gt; means
that &lt;span class=&quot;math inline&quot;&gt;\(\theta_i/(\tau_i\cdot l_i)\)&lt;/span&gt; is
constant and does not depend on &lt;span class=&quot;math inline&quot;&gt;\(i\)&lt;/span&gt;.
Similarly, &lt;span class=&quot;math inline&quot;&gt;\(p(\theta)\propto 1\)&lt;/span&gt; means
that &lt;span class=&quot;math inline&quot;&gt;\(\theta\)&lt;/span&gt; has a constant
(uniform) probability density.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Vectors of parameters are denoted by letters without indices:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span class=&quot;math inline&quot;&gt;\(R=(R_1, \ldots, R_N)\)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span class=&quot;math inline&quot;&gt;\(G=(G_1, \ldots, G_N)\)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span class=&quot;math inline&quot;&gt;\(S=(S_1, \ldots, S_N)\)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span class=&quot;math inline&quot;&gt;\(\tau=(\tau_1, \ldots,
\tau_M)\)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span class=&quot;math inline&quot;&gt;\(\theta=(\theta_1, \ldots,
\theta_M)\)&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;span class=&quot;math inline&quot;&gt;\(\mathbb{I}\)&lt;/span&gt; is the indicator
function: &lt;span class=&quot;math inline&quot;&gt;\(\mathbb{I}_p\)&lt;/span&gt; is equal to
&lt;span class=&quot;math inline&quot;&gt;\(1\)&lt;/span&gt; if &lt;span
class=&quot;math inline&quot;&gt;\(p\)&lt;/span&gt; is true and &lt;span
class=&quot;math inline&quot;&gt;\(0\)&lt;/span&gt; otherwise.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Thus, we have five vector-valued random variables (of different
dimensions!): &lt;span class=&quot;math inline&quot;&gt;\(\theta, \tau, G, S,
R\)&lt;/span&gt;. Of these, &lt;span class=&quot;math inline&quot;&gt;\(R\)&lt;/span&gt; is the
observed data, and &lt;span class=&quot;math inline&quot;&gt;\(\theta\)&lt;/span&gt; and &lt;span
class=&quot;math inline&quot;&gt;\(\tau\)&lt;/span&gt; are the unknown parameters that we
wish to estimate from the data. &lt;span class=&quot;math inline&quot;&gt;\(G\)&lt;/span&gt;
and &lt;span class=&quot;math inline&quot;&gt;\(S\)&lt;/span&gt; are unobserved variables that
we are not directly interested in, but they are necessary to build the
model.&lt;/p&gt;
&lt;p&gt;Vectors &lt;span class=&quot;math inline&quot;&gt;\(\tau\)&lt;/span&gt; and &lt;span
class=&quot;math inline&quot;&gt;\(\theta\)&lt;/span&gt; are equivalent in the sense that
they carry the same information, just on different scales. Once we
estimate &lt;span class=&quot;math inline&quot;&gt;\(\theta\)&lt;/span&gt;, we can get an
equivalent estimate of &lt;span class=&quot;math inline&quot;&gt;\(\tau\)&lt;/span&gt;, and
vice versa, using the conversion formulae given above.&lt;/p&gt;
&lt;p&gt;We call &lt;span class=&quot;math inline&quot;&gt;\(\theta\)&lt;/span&gt; a random variable
in the Bayesian sense. It is random because its value is not known and
some values of &lt;span class=&quot;math inline&quot;&gt;\(\theta\)&lt;/span&gt; are more
consistent with the data than the others. There is no particular random
process that generates &lt;span class=&quot;math inline&quot;&gt;\(\theta\)&lt;/span&gt;, so
it is not random in the classical (frequentist) sense.&lt;/p&gt;
&lt;h2 id=&quot;probabilistic-approach&quot;&gt;Probabilistic approach&lt;/h2&gt;
&lt;p&gt;What does an estimate of &lt;span class=&quot;math inline&quot;&gt;\(\theta\)&lt;/span&gt;
(or &lt;span class=&quot;math inline&quot;&gt;\(\tau\)&lt;/span&gt;, which is usually more
interesting) look like? The most general form is the full posterior
probability distribution &lt;span class=&quot;math inline&quot;&gt;\(p(\tau|R)\)&lt;/span&gt;.
In practice, we need to summarize the distribution to make sense of it.
Some useful summaries are:&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;The maximum a posteriori (MAP) value, or the mode of the posterior
distribution, is the value of &lt;span class=&quot;math inline&quot;&gt;\(\tau\)&lt;/span&gt;
for which &lt;span class=&quot;math inline&quot;&gt;\(p(\tau|R)\)&lt;/span&gt; has the
greatest possible value. This is, roughly speaking, the most likely
value of &lt;span class=&quot;math inline&quot;&gt;\(\tau\)&lt;/span&gt; under our model given
the observed data.&lt;/li&gt;
&lt;li&gt;An uncertainty interval &lt;span class=&quot;math inline&quot;&gt;\((\tau^1,
\tau^2)\)&lt;/span&gt; at level &lt;span class=&quot;math inline&quot;&gt;\(\gamma\)&lt;/span&gt;
gives a plausible range of values that &lt;span
class=&quot;math inline&quot;&gt;\(\tau\)&lt;/span&gt; might take: &lt;span
class=&quot;math display&quot;&gt;\[p(\tau^1 &amp;lt; \tau &amp;lt;
\tau^2|R)=\gamma.\]&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;If we are interested in one or a handful of genes or isoforms, we
may want to plot the marginal distributions &lt;span
class=&quot;math inline&quot;&gt;\(p(\tau_i|R)\)&lt;/span&gt;.&lt;/li&gt;
&lt;li&gt;If we are interested in the differential expression of isoforms
&lt;span class=&quot;math inline&quot;&gt;\(i\)&lt;/span&gt; and &lt;span
class=&quot;math inline&quot;&gt;\(k\)&lt;/span&gt; within the same experiment, we can
compute &lt;span class=&quot;math display&quot;&gt;\[p(\tau_i &amp;gt; \tau_k|R).\]&lt;/span&gt;
Or, we can compare expression in two independent experiments &lt;span
class=&quot;math inline&quot;&gt;\((\tau, R)\)&lt;/span&gt; and &lt;span
class=&quot;math inline&quot;&gt;\((\tau&amp;#39;,R&amp;#39;)\)&lt;/span&gt; by computing &lt;span
class=&quot;math display&quot;&gt;\[p(\tau_i &amp;gt;
\tau_i&amp;#39;|R,R&amp;#39;).\]&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;generative-model&quot;&gt;Generative model&lt;/h2&gt;
&lt;p&gt;We begin by formulating a &lt;em&gt;generative model&lt;/em&gt;, a probabilistic
process that conceptually generates our data.&lt;/p&gt;
&lt;p&gt;Li et al. suggest a model where &lt;span
class=&quot;math inline&quot;&gt;\(G_n\)&lt;/span&gt;, &lt;span
class=&quot;math inline&quot;&gt;\(S_n\)&lt;/span&gt;, and &lt;span
class=&quot;math inline&quot;&gt;\(R_n\)&lt;/span&gt; are generated for every &lt;span
class=&quot;math inline&quot;&gt;\(n\)&lt;/span&gt; as follows:&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;&lt;p&gt;Draw &lt;span class=&quot;math inline&quot;&gt;\(G_n\)&lt;/span&gt; from the set &lt;span
class=&quot;math inline&quot;&gt;\(\{1,\ldots,M\}\)&lt;/span&gt; of all isoforms according
to the probabilities &lt;span class=&quot;math inline&quot;&gt;\(\theta\)&lt;/span&gt;: &lt;span
class=&quot;math display&quot;&gt;\[p(G_n=i|\theta)=\theta_i.\]&lt;/span&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Choose where on the isoform the read will start according to the
&lt;em&gt;read start position distribution (RSPD)&lt;/em&gt; &lt;span
class=&quot;math inline&quot;&gt;\(p(S_n|G_n)\)&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;The authors suggest two uniform distributions: for poly(A)+ RNA &lt;span
class=&quot;math display&quot;&gt;\[p(S_n=j|G_n=i)=\frac{1}{l_i} \cdot
\mathbb{I}_{1\leq j\leq l_i}\]&lt;/span&gt; and for poly(A)- RNA &lt;span
class=&quot;math display&quot;&gt;\[p(S_n=j|G_n=i)=\frac{1}{l_i-L+1} \cdot
\mathbb{I}_{1\leq j\leq (l_i-L+1)}.\]&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;The exact form of the RSPD doesn’t matter as long as it is known in
advance. The paper also shows how to estimate the RSPD from data; we
will not cover that here.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The read &lt;span class=&quot;math inline&quot;&gt;\(R_n\)&lt;/span&gt; is generated by
sequencing the isoform &lt;span class=&quot;math inline&quot;&gt;\(G_n\)&lt;/span&gt; starting
from the position &lt;span class=&quot;math inline&quot;&gt;\(S_n\)&lt;/span&gt;. If
sequencing was perfect, this would be deterministic: &lt;span
class=&quot;math inline&quot;&gt;\(R_n\)&lt;/span&gt; would contain exactly the bases &lt;span
class=&quot;math inline&quot;&gt;\(S_n, S_n+1, \ldots, S_n+L-1\)&lt;/span&gt; from &lt;span
class=&quot;math inline&quot;&gt;\(G_n\)&lt;/span&gt;. In reality, sequencing errors
happen, and we can read a slightly different sequence. Hence &lt;span
class=&quot;math inline&quot;&gt;\(R_n\)&lt;/span&gt; is also a random variable with some
conditional distribution &lt;span
class=&quot;math inline&quot;&gt;\(p(R_n|G_n,S_n)\)&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;As with RSPD, we don’t care about the particular form of the
conditional probability &lt;span
class=&quot;math inline&quot;&gt;\(p(R_n|G_n,S_n)\)&lt;/span&gt;. In the simplest case, it
would assign a fixed probability such as &lt;span
class=&quot;math inline&quot;&gt;\(10^{-3}\)&lt;/span&gt; to each mismatch between the read
and the isoform. More realistically, the error probability would
increase towards the end of the read. Better yet, we could extend the
model to take quality scores into account.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Note that this model does not accurately represent the physics of an
RNA-Seq experiment. In particular, it does not model fragmentation.
Essentially, the model assumes that the fragment size is constant and
equal to the read length. This is addressed in the &lt;a
href=&quot;http://bmcbioinformatics.biomedcentral.com/articles/10.1186/1471-2105-12-323&quot;&gt;2011
paper&lt;/a&gt;, although the model there is still backwards: they first pick
an isoform and then a fragment from it, whereas in reality we pick a
fragment at random from a common pool, and that determines the isoform.
This is the reason why &lt;span class=&quot;math inline&quot;&gt;\(\theta\)&lt;/span&gt; does
not represent the isoform frequencies and has to be further normalized
by the isoform lengths to obtain &lt;span
class=&quot;math inline&quot;&gt;\(\tau\)&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;A generative model does not have to match exactly the true data
generation process as long as the joint distribution &lt;span
class=&quot;math inline&quot;&gt;\(p(G,S,R|\theta)\)&lt;/span&gt; fits the reality. Here,
the authors saw a way to simplify a model without sacrificing its
adequacy much.&lt;/p&gt;
&lt;p&gt;This model describes the following &lt;a
href=&quot;https://en.wikipedia.org/wiki/Bayesian_network&quot;&gt;Bayesian
network&lt;/a&gt;:&lt;/p&gt;
&lt;figure&gt;
&lt;img src=&quot;/img/rsem-bayesnet.svg&quot; style=&quot;width: 90%; max-height: 150px;&quot;&gt;
&lt;/figure&gt;
&lt;p&gt;We can write the joint probability as &lt;span
class=&quot;math display&quot;&gt;\[p(G,S,R|\theta)=\prod_{n=1}^N
p(G_n,S_n,R_n|\theta)=\prod_{n=1}^N
p(G_n|\theta)p(S_n|G_n)p(R_n|G_n,S_n)\label{JOINT}\tag{JOINT}.\]&lt;/span&gt;&lt;/p&gt;
&lt;h2 id=&quot;finding-theta&quot;&gt;Finding &lt;span
class=&quot;math inline&quot;&gt;\(\theta\)&lt;/span&gt;&lt;/h2&gt;
&lt;p&gt;How do we get from &lt;span
class=&quot;math inline&quot;&gt;\(p(G,S,R|\theta)\)&lt;/span&gt; to &lt;span
class=&quot;math inline&quot;&gt;\(p(\theta|R)\)&lt;/span&gt;?&lt;/p&gt;
&lt;p&gt;We start by marginalizing out the unknowns &lt;span
class=&quot;math inline&quot;&gt;\(G_n\)&lt;/span&gt; and &lt;span
class=&quot;math inline&quot;&gt;\(S_n\)&lt;/span&gt;:&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;math display&quot;&gt;\[\begin{align*}
p(R|\theta)=\prod_{n=1}^N p(R_n|\theta) &amp;amp; =
\prod_{n=1}^N\sum_{i=1}^M\sum_{j=1}^{l_i} p(R_n,G_n=i,S_n=j|\theta) \\
&amp;amp;=\prod_{n=1}^N\sum_{i=1}^M\sum_{j=1}^{l_i} p(R_n|G_n=i,S_n=j)
p(S_n|G_n) \theta_i
.
\end{align*}\]&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Then apply Bayes’ theorem to find &lt;span
class=&quot;math inline&quot;&gt;\(\theta\)&lt;/span&gt;:&lt;/p&gt;
&lt;p&gt;&lt;span
class=&quot;math display&quot;&gt;\[p(\theta|R)=\frac{p(R|\theta)p(\theta)}{p(R)}.\]&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;We could expand &lt;span class=&quot;math inline&quot;&gt;\(p(R)\)&lt;/span&gt; as &lt;span
class=&quot;math inline&quot;&gt;\(\int p(R|\theta)p(\theta)d\theta\)&lt;/span&gt;, but
since &lt;span class=&quot;math inline&quot;&gt;\(p(R)\)&lt;/span&gt; does not depend on &lt;span
class=&quot;math inline&quot;&gt;\(\theta\)&lt;/span&gt;, we won’t need to calculate
it.&lt;/p&gt;
&lt;h2 id=&quot;choosing-the-prior&quot;&gt;Choosing the prior&lt;/h2&gt;
&lt;p&gt;&lt;span class=&quot;math inline&quot;&gt;\(p(\theta)\)&lt;/span&gt; is the prior
probability density of &lt;span class=&quot;math inline&quot;&gt;\(\theta\)&lt;/span&gt;.
Let’s pretend that we do not have any prior information on the isoform
expression levels. Then it may seem reasonable to assume a uniform prior
probability density &lt;span class=&quot;math inline&quot;&gt;\(p(\theta)\propto
1\)&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;There is a subtle issue with this. Recall that the isoform expression
levels are represented by the vector &lt;span
class=&quot;math inline&quot;&gt;\(\tau\)&lt;/span&gt;, not &lt;span
class=&quot;math inline&quot;&gt;\(\theta\)&lt;/span&gt;. The vector &lt;span
class=&quot;math inline&quot;&gt;\(\theta\)&lt;/span&gt; is “inflated” by the isoform
lengths to account for the effect that longer isoforms produce more
reads.&lt;/p&gt;
&lt;p&gt;Therefore, the prior &lt;span class=&quot;math inline&quot;&gt;\(p(\theta)\propto
1\)&lt;/span&gt; corresponds to the (unfounded) assumption that shorter
isoforms are somehow a priori more expressed than longer ones.&lt;/p&gt;
&lt;p&gt;A better prior for &lt;span class=&quot;math inline&quot;&gt;\(\theta\)&lt;/span&gt; might
be the one for which the vector &lt;span
class=&quot;math display&quot;&gt;\[\tau(\theta)=(\tau_1(\theta),\ldots,\tau_M(\theta))=\left(\frac{\theta_1/l_1}{\sum_{k=1}^M
\theta_k/l_k},\ldots,\frac{\theta_M/l_M}{\sum_{k=1}^M
\theta_k/l_k}\right)\]&lt;/span&gt; is uniformly distributed on the unit
simplex. The probability density of such distribution is&lt;/p&gt;
&lt;p&gt;&lt;span
class=&quot;math display&quot;&gt;\[p(\theta)=(n-1)!\cdot\frac{\partial(\tau_1,\ldots,\tau_{M-1})}{\partial(\theta_1,\ldots,\theta_{M-1})},\]&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;where the “fraction” on the right is the Jacobian determinant. (We
parameterize &lt;span class=&quot;math inline&quot;&gt;\(\theta\)&lt;/span&gt; and &lt;span
class=&quot;math inline&quot;&gt;\(\tau\)&lt;/span&gt; distributions by the first &lt;span
class=&quot;math inline&quot;&gt;\(M-1\)&lt;/span&gt; vector components, viewing &lt;span
class=&quot;math inline&quot;&gt;\(\theta_M=1-\sum_{k=1}^{M-1}\theta_k\)&lt;/span&gt; and
&lt;span class=&quot;math inline&quot;&gt;\(\tau_M=1-\sum_{k=1}^{M-1} \tau_k\)&lt;/span&gt; as
functions.)&lt;/p&gt;
&lt;p&gt;How much do the different priors affect the results? It is not clear.
Li et al. use the uniform prior on &lt;span
class=&quot;math inline&quot;&gt;\(\theta\)&lt;/span&gt; implicitly in the &lt;a
href=&quot;https://academic.oup.com/bioinformatics/article-lookup/doi/10.1093/bioinformatics/btp692&quot;&gt;2009
paper&lt;/a&gt; by computing the maximum likelihood estimate and explicitly in
the &lt;a
href=&quot;http://bmcbioinformatics.biomedcentral.com/articles/10.1186/1471-2105-12-323&quot;&gt;2011
paper&lt;/a&gt;, when computing credible intervals. In the latter paper, they
note:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;CIs estimated from data simulated with the mouse Ensembl annotation
were less accurate (Additional file 7). We investigated why the CIs were
less accurate on this set and found that many of the CIs were biased
downward due to the Dirichlet prior and the larger number of transcripts
in the Ensembl set.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I haven’t tested yet whether the uniform &lt;span
class=&quot;math inline&quot;&gt;\(\tau\)&lt;/span&gt; prior improves these CIs.&lt;/p&gt;
&lt;p&gt;In this article, we will follow the lead of Li et al. and assume
&lt;span class=&quot;math inline&quot;&gt;\(p(\theta)\propto 1\)&lt;/span&gt;.&lt;/p&gt;
&lt;h2 id=&quot;em-explanation&quot;&gt;EM explanation&lt;/h2&gt;
&lt;p&gt;The EM (“expectation-maximization”) algorithm is used to find the
maximum a posteriori estimate of &lt;span
class=&quot;math inline&quot;&gt;\(\theta\)&lt;/span&gt;. As Li et al. point out, the EM
algorithm can be viewed as repeated “rescuing” of multireads. Let’s see
what that means.&lt;/p&gt;
&lt;p&gt;In this section, we will assume that a read either maps to an isoform
perfectly or does not map to it at all, and that it can map to each
isoform only once (though it can map to several isoforms at the same
time). This is just to simplify the presentation. The algorithm and its
derivation, which are presented in the next section, can handle the
general case.&lt;/p&gt;
&lt;h3 id=&quot;intuition&quot;&gt;Intuition&lt;/h3&gt;
&lt;p&gt;First, consider a case of only two expressed isoforms (&lt;span
class=&quot;math inline&quot;&gt;\(M=2\)&lt;/span&gt;). In general, there will be some
number of reads, say, &lt;span class=&quot;math inline&quot;&gt;\(N_1\)&lt;/span&gt;, that map
only to isoform 1, some other number, &lt;span
class=&quot;math inline&quot;&gt;\(N_2\)&lt;/span&gt;, of reads that map only to isoform 2.
Finally, there will be &lt;span
class=&quot;math inline&quot;&gt;\(N_{12}=N-N_1-N_2\)&lt;/span&gt; reads that map equally
well to both isoforms.&lt;/p&gt;
&lt;p&gt;The easiest way to estimate &lt;span
class=&quot;math inline&quot;&gt;\(\theta\)&lt;/span&gt; is by considering only
unambiguously mapped reads. This leads to the “zeroth”
approximations&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;math display&quot;&gt;\[\begin{align*}
\theta^{(0)}_1&amp;amp;=N_1/(N_1+N_2),\\
\theta^{(0)}_2&amp;amp;=N_2/(N_1+N_2).
\end{align*}\]&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;This is the best we can do considering just &lt;span
class=&quot;math inline&quot;&gt;\(N_1\)&lt;/span&gt; and &lt;span
class=&quot;math inline&quot;&gt;\(N_2\)&lt;/span&gt;. To improve our estimate, we need to
extract some information from &lt;span
class=&quot;math inline&quot;&gt;\(N_{12}\)&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;Consider a particular multiread &lt;span
class=&quot;math inline&quot;&gt;\(n\)&lt;/span&gt;. Can we guess to which isoform it
belongs? No, it maps equally well to both. But can we guess &lt;em&gt;how
many&lt;/em&gt; of the multireads come from each isoform? The more expressed
an isoform is, the more reads we expect it to contribute to &lt;span
class=&quot;math inline&quot;&gt;\(N_{12}\)&lt;/span&gt;. How do we know how much each
isoform is expressed? We don’t — if we knew, we wouldn’t need the
algorithm — but we can make a reasonable guess based on the estimate
&lt;span class=&quot;math inline&quot;&gt;\(\theta^{(0)}\)&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;We need to be careful, though. Would it be valid to estimate the
fraction of ambiguous reads that come from isoform 1 as &lt;span
class=&quot;math inline&quot;&gt;\(\theta^{(0)}_1\)&lt;/span&gt;?&lt;/p&gt;
&lt;p&gt;Suppose that isoform 1 is much shorter than isoform 2: &lt;span
class=&quot;math inline&quot;&gt;\(l_1 \ll l_2\)&lt;/span&gt;. Now consider any particular
ambiguous read &lt;span class=&quot;math inline&quot;&gt;\(R_n\)&lt;/span&gt;. Does the fact
that &lt;span class=&quot;math inline&quot;&gt;\(l_1 \ll l_2\)&lt;/span&gt; increase the
probability that this read comes from the longer isoform, i.e. that
&lt;span class=&quot;math inline&quot;&gt;\(G_n=2\)&lt;/span&gt;?&lt;/p&gt;
&lt;p&gt;No — because, according to our assumptions made earlier in this
section, &lt;span class=&quot;math inline&quot;&gt;\(R_n\)&lt;/span&gt; maps to either isoform
only once. The number of &lt;em&gt;all&lt;/em&gt; fragments produced by isoform
&lt;span class=&quot;math inline&quot;&gt;\(i\)&lt;/span&gt; is proportional to &lt;span
class=&quot;math inline&quot;&gt;\(\theta_i\)&lt;/span&gt;; but the number of fragments
&lt;em&gt;capable of producing a particular read&lt;/em&gt;, &lt;span
class=&quot;math inline&quot;&gt;\(R_n\)&lt;/span&gt;, is proportional to the transcript
abundance, &lt;span class=&quot;math inline&quot;&gt;\(\tau_i\)&lt;/span&gt;. The longer an
isoform, the more fragments it will produce, but also the lower fraction
of these fragments will look anything like &lt;span
class=&quot;math inline&quot;&gt;\(R_n\)&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;Therefore, we partition the &lt;span
class=&quot;math inline&quot;&gt;\(N_{12}\)&lt;/span&gt; ambiguous reads between the two
isoforms in proportion &lt;span
class=&quot;math inline&quot;&gt;\(\tau^{(0)}_1:\tau^{(0)}_2\)&lt;/span&gt;, where &lt;span
class=&quot;math inline&quot;&gt;\(\tau^{(0)}\)&lt;/span&gt; is derived from &lt;span
class=&quot;math inline&quot;&gt;\(\theta^{(0)}\)&lt;/span&gt; according to the usual
formula (see Notation and variables).&lt;/p&gt;
&lt;p&gt;Partitioning the multireads gives us the updated counts: &lt;span
class=&quot;math inline&quot;&gt;\(N_1 + N_{12}\cdot\tau^{(0)}_1\)&lt;/span&gt; for isoform
1 vs. &lt;span class=&quot;math inline&quot;&gt;\(N_2 + N_{12}\cdot\tau^{(0)}_2\)&lt;/span&gt;
for isoform 2. These updated counts lead us to a new estimate of &lt;span
class=&quot;math inline&quot;&gt;\(\theta\)&lt;/span&gt;, &lt;span
class=&quot;math inline&quot;&gt;\(\theta^{(1)}\)&lt;/span&gt;: &lt;span
class=&quot;math display&quot;&gt;\[\theta^{(1)}_i =
\frac{N_i+N_{12}\cdot\tau^{(0)}_i}{N}.\]&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;And the cycle repeats. We can repeat this procedure until we notice
that &lt;span class=&quot;math inline&quot;&gt;\(\theta^{(r+1)}\)&lt;/span&gt; does not differ
much from &lt;span class=&quot;math inline&quot;&gt;\(\theta^{(r)}\)&lt;/span&gt;.&lt;/p&gt;
&lt;h3 id=&quot;simulation&quot;&gt;Simulation&lt;/h3&gt;
&lt;p&gt;For a higher number of isoforms, the computations are analogous. To
see how this works out in practice, consider the following simulated
example with 3 isoforms. You can download &lt;a
href=&quot;/files/2017-01-29-rsem/trace.R&quot;&gt;the R script performing the
simulation&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The true values of &lt;span class=&quot;math inline&quot;&gt;\(l\)&lt;/span&gt; and &lt;span
class=&quot;math inline&quot;&gt;\(\theta\)&lt;/span&gt; are:&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;math display&quot;&gt;\[
\begin{array}{c|rr}
i &amp;amp; l_i  &amp;amp; \theta_i \\ \hline
1 &amp;amp; 300 &amp;amp; 0.60 \\
2 &amp;amp; 1000 &amp;amp; 0.10 \\
3 &amp;amp; 2000 &amp;amp; 0.30 \\
\end{array}
\]&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;The counts obtained from a thousand RNA-Seq reads are:&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;math display&quot;&gt;\[
\begin{array}{lll}
N_1 = 111 &amp;amp; N_{12} = 69  &amp;amp; N_{123} = 144 \\
N_2 = 26  &amp;amp; N_{13} = 311 \\
N_3 = 186 &amp;amp; N_{23} = 153 \\
\end{array}
\]&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Amazingly, under the assumptions introduced in this section, we don’t
need to know the actual reads and how they map to the isoforms — we only
need the six numbers above.&lt;/p&gt;
&lt;p&gt;The first five successive approximations for &lt;span
class=&quot;math inline&quot;&gt;\(\theta\)&lt;/span&gt; made by the EM algorithm are:&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;math display&quot;&gt;\[
\begin{array}{r|rrrrr}
i &amp;amp; \theta^{(0)}_i &amp;amp; \theta^{(1)}_i &amp;amp; \theta^{(2)}_i &amp;amp;
\theta^{(3)}_i &amp;amp; \theta^{(4)}_i \\
\hline
1 &amp;amp; 0.34 &amp;amp; 0.53 &amp;amp; 0.58 &amp;amp; 0.59 &amp;amp; 0.59 \\
2 &amp;amp; 0.08 &amp;amp; 0.07 &amp;amp; 0.07 &amp;amp; 0.08 &amp;amp; 0.08 \\
3 &amp;amp; 0.58 &amp;amp; 0.40 &amp;amp; 0.34 &amp;amp; 0.33 &amp;amp; 0.32 \\
\end{array}
\]&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;The zeroth approximation, &lt;span
class=&quot;math inline&quot;&gt;\(\theta^{(0)}\)&lt;/span&gt;, is not very accurate, but
then it quickly gets much better:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/img/rsem_error.png&quot; /&gt;&lt;/p&gt;
&lt;h2 id=&quot;em-derivation&quot;&gt;EM derivation&lt;/h2&gt;
&lt;p&gt;Now suppose our current estimate for &lt;span
class=&quot;math inline&quot;&gt;\(\theta\)&lt;/span&gt; is &lt;span
class=&quot;math inline&quot;&gt;\(\theta^{(r)}=\theta^*\)&lt;/span&gt;; let’s see how we
can improve it to get &lt;span
class=&quot;math inline&quot;&gt;\(\theta^{(r+1)}\)&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;We start with the following algebraic identity:&lt;/p&gt;
&lt;p&gt;&lt;span
class=&quot;math display&quot;&gt;\[p(\theta|R)=\frac{p(\theta,G,S|R)}{p(G,S|\theta,R)}.\]&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Apply logarithms:&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;math display&quot;&gt;\[
\log p(\theta|R)=\log p(\theta,G,S|R) - \log
p(G,S|\theta,R)\tag{EM1}\label{EM1}.
\]&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Define the following operator, &lt;span
class=&quot;math inline&quot;&gt;\(E^*\)&lt;/span&gt;, which takes the expectation of a
function &lt;span class=&quot;math inline&quot;&gt;\(X(G,S)\)&lt;/span&gt; with respect to
&lt;span class=&quot;math inline&quot;&gt;\(G\)&lt;/span&gt; and &lt;span
class=&quot;math inline&quot;&gt;\(S\)&lt;/span&gt; under the distribution &lt;span
class=&quot;math inline&quot;&gt;\(p(G,S|\theta^*,R)\)&lt;/span&gt;: &lt;span
class=&quot;math display&quot;&gt;\[E^*(X)=\sum_G\sum_S X(G,S)\cdot
p(G,S|\theta^*,R).\]&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Applying this operator to both sides of &lt;span
class=&quot;math inline&quot;&gt;\(\ref{EM1}\)&lt;/span&gt; gives:&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;math display&quot;&gt;\[\log p(\theta|R)=E^*(\log
p(\theta,G,S|R)) - E^*(\log
p(G,S|\theta,R)).\tag{EM2}\label{EM2}\]&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;It is important to realize that we are not approximating anything yet
or introducing any new assumptions (e.g. that &lt;span
class=&quot;math inline&quot;&gt;\(G\)&lt;/span&gt; and &lt;span
class=&quot;math inline&quot;&gt;\(S\)&lt;/span&gt; follow a certain distribution).
Everything up to this point is algebraic identities.&lt;/p&gt;
&lt;p&gt;Now, our goal is to find &lt;span class=&quot;math inline&quot;&gt;\(\theta\)&lt;/span&gt;
that is a better estimate than &lt;span
class=&quot;math inline&quot;&gt;\(\theta^*\)&lt;/span&gt;: &lt;span
class=&quot;math inline&quot;&gt;\(p(\theta|R) &amp;gt; p(\theta^*|R)\)&lt;/span&gt;. That
means increasing the right hand side of &lt;span
class=&quot;math inline&quot;&gt;\(\ref{EM2}\)&lt;/span&gt; compared to its value at &lt;span
class=&quot;math inline&quot;&gt;\(\theta=\theta^*\)&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;The significance of the conditional distribution used in &lt;span
class=&quot;math inline&quot;&gt;\(E^*\)&lt;/span&gt; is that the term &lt;span
class=&quot;math inline&quot;&gt;\(- E^*(\log p(G,S|\theta,R))\)&lt;/span&gt; will be
increased no matter what we set &lt;span
class=&quot;math inline&quot;&gt;\(\theta\)&lt;/span&gt; to. This is because &lt;span
class=&quot;math inline&quot;&gt;\(- E^*(\log p(G,S|\theta,R))\)&lt;/span&gt; is the &lt;a
href=&quot;https://en.wikipedia.org/wiki/Cross_entropy&quot;&gt;cross entropy&lt;/a&gt;
between the distributions &lt;span
class=&quot;math inline&quot;&gt;\(p(G,S|\theta^*,R)\)&lt;/span&gt; and &lt;span
class=&quot;math inline&quot;&gt;\(p(G,S|\theta,R)\)&lt;/span&gt;. By &lt;a
href=&quot;https://en.wikipedia.org/wiki/Gibbs&amp;#39;_inequality&quot;&gt;Gibbs’
inequality&lt;/a&gt;, the cross entropy is at its minimum at &lt;span
class=&quot;math inline&quot;&gt;\(\theta=\theta^*\)&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;Thus, we only need to increase — ideally, maximize — the other term
in &lt;span class=&quot;math inline&quot;&gt;\(\ref{EM2}\)&lt;/span&gt;, &lt;span
class=&quot;math inline&quot;&gt;\(E^*(\log p(\theta,G,S|R))\)&lt;/span&gt;. This is called
the &lt;em&gt;expected complete-data log-likelihood&lt;/em&gt;. Now it’s time to
exploit the Bayesian network of our generative model:&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;math display&quot;&gt;\[
p(\theta,G,S|R) = \frac{p(R,G,S,\theta)}{p(R)} =
\frac{p(R|G,S)p(S|G)p(G|\theta)p(\theta)}{p(R)},
\]&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;math display&quot;&gt;\[\begin{align*}
E^*(\log p(\theta,G,S|R)) &amp;amp; = E^*(\log p(R|G,S))\\
&amp;amp;+E^*(\log p(S|G))\\
&amp;amp;+E^*(\log p(G|\theta))\\
&amp;amp;+\log p(\theta)\\
&amp;amp;-\log p(R).
\end{align*}\]&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;In the above sum, assuming the uniform prior, only one term depends
on &lt;span class=&quot;math inline&quot;&gt;\(\theta\)&lt;/span&gt;: &lt;span
class=&quot;math inline&quot;&gt;\(E^*(\log p(G|\theta))\)&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;math display&quot;&gt;\[\begin{align*}
E^*(\log p(G|\theta))&amp;amp;=E^*(\log\prod_{n=1}^N p(G_n|\theta))\\
&amp;amp; =\sum_{n=1}^N E^*\log p(G_n|\theta) \\
&amp;amp; =\sum_{n=1}^N\sum_{i=1}^M \log\theta_i \cdot p(G_n=i|\theta^*,
R_n) \\
&amp;amp; =\sum_{i=1}^M a_i\log \theta_i,
\end{align*}\]&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;where the coefficients &lt;span class=&quot;math inline&quot;&gt;\(a_i\)&lt;/span&gt; can
be computed by applying Bayes’ theorem and &lt;span
class=&quot;math inline&quot;&gt;\(\ref{JOINT}\)&lt;/span&gt;:&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;math display&quot;&gt;\[\begin{align*}
a_i&amp;amp;=\sum_{n=1}^N p(G_n=i|\theta^*, R_n)\\
&amp;amp;=\sum_{n=1}^N  \frac
  {\sum_{j=1}^{l_i} p(R_n|G_n=i,S_n=j)\cdot \tau_i^*}
  {\sum_{k=1}^M\sum_{j=1}^{l_k} p(R_n|G_n=k,S_n=j)\cdot \tau_k^*}
\end{align*}\]&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;We need to maximize &lt;span class=&quot;math inline&quot;&gt;\(f(\theta)=\sum_i
a_i\log \theta_i\)&lt;/span&gt; subject to &lt;span
class=&quot;math inline&quot;&gt;\(g(\theta)=\sum_i\theta_i=1\)&lt;/span&gt; and &lt;span
class=&quot;math inline&quot;&gt;\(\theta_i\geq 0\)&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;The &lt;a
href=&quot;https://en.wikipedia.org/wiki/Lagrange_multiplier&quot;&gt;method of
Lagrange multipliers&lt;/a&gt; gives the following necessary condition for the
extremum of &lt;span class=&quot;math inline&quot;&gt;\(f(\theta)\)&lt;/span&gt;:&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;math display&quot;&gt;\[\frac{\partial f}{\partial
\theta_i}=\lambda\frac{\partial g}{\partial \theta_i},\]&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;or &lt;span class=&quot;math inline&quot;&gt;\(\theta_i=a_i/\lambda\)&lt;/span&gt;. Since
&lt;span class=&quot;math inline&quot;&gt;\(\sum_i\theta_i=1\)&lt;/span&gt;, &lt;span
class=&quot;math inline&quot;&gt;\(\lambda=\sum_i a_i\)&lt;/span&gt; and &lt;span
class=&quot;math inline&quot;&gt;\(\theta_i=a_i/\sum_k a_k\)&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;The function &lt;span class=&quot;math inline&quot;&gt;\(f\)&lt;/span&gt; is concave (as a
weighted sum of logarithms) and goes to &lt;span
class=&quot;math inline&quot;&gt;\(-\infty\)&lt;/span&gt; at the boundary &lt;span
class=&quot;math inline&quot;&gt;\(\theta_i=0\)&lt;/span&gt; when &lt;span
class=&quot;math inline&quot;&gt;\(a_i&amp;gt;0\)&lt;/span&gt;, therefore, &lt;span
class=&quot;math display&quot;&gt;\[\theta_i=\frac{a_i}{\sum_{k=1}^M a_k}\]&lt;/span&gt; is
the global maximum of &lt;span class=&quot;math inline&quot;&gt;\(f\)&lt;/span&gt; under the
constraints and should be taken as the next estimate of the true &lt;span
class=&quot;math inline&quot;&gt;\(\theta\)&lt;/span&gt;.&lt;/p&gt;
&lt;h2 id=&quot;approximation-via-alignment&quot;&gt;Approximation via alignment&lt;/h2&gt;
&lt;p&gt;Consider the probabilities &lt;span
class=&quot;math inline&quot;&gt;\(p(R_n|G_n=i,S_n=j)\)&lt;/span&gt; that are used to
compute &lt;span class=&quot;math inline&quot;&gt;\(a_i\)&lt;/span&gt;. The probability that
&lt;span class=&quot;math inline&quot;&gt;\(R_n\)&lt;/span&gt; could have originated from
isoform &lt;span class=&quot;math inline&quot;&gt;\(i\)&lt;/span&gt; at position &lt;span
class=&quot;math inline&quot;&gt;\(j\)&lt;/span&gt; exponentially decreases with every
mismatch between the sequences of the read and the isoform.&lt;/p&gt;
&lt;p&gt;For any given read, most of the pairs &lt;span
class=&quot;math inline&quot;&gt;\((i,j)\)&lt;/span&gt; will result in unrelated dissimilar
sequences, which therefore contribute almost nothing to the sum &lt;span
class=&quot;math inline&quot;&gt;\(\sum_{j=1}^{l_i} p(R_n|G_n=i,S_n=j)\cdot
\tau_i^*\)&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;If we approximate these tiny probabilities by &lt;span
class=&quot;math inline&quot;&gt;\(0\)&lt;/span&gt;, we can replace the whole sum with the
sum over only those &lt;span class=&quot;math inline&quot;&gt;\(j\)&lt;/span&gt; for which
&lt;span class=&quot;math inline&quot;&gt;\(R_n\)&lt;/span&gt; aligns well to isoform &lt;span
class=&quot;math inline&quot;&gt;\(i\)&lt;/span&gt; at position &lt;span
class=&quot;math inline&quot;&gt;\(j\)&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;The only concern here is to keep the denominator from getting close
to &lt;span class=&quot;math inline&quot;&gt;\(0\)&lt;/span&gt;. In our case, the denominator
is always greater than the numerator, so the only thing we need to worry
about is if all the terms get approximated by &lt;span
class=&quot;math inline&quot;&gt;\(0\)&lt;/span&gt;, that is, the read does not map to
anything. This is one of the reasons why Li et al. introduce the noise
isoform, which never gets replaced by &lt;span
class=&quot;math inline&quot;&gt;\(0\)&lt;/span&gt;. An alternative is simply to ignore the
reads that do not map anywhere.&lt;/p&gt;
&lt;h2 id=&quot;see-also&quot;&gt;See also&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://doi.org/10.1101/503672&quot;&gt;A revisit of RSEM generative
model and its EM algorithm for quantifying transcript
abundances.&lt;/a&gt;&lt;/p&gt;
</description>
                        <pubDate>Sun, 29 Jan 2017 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2017-01-29-rsem</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2017-01-29-rsem.html</guid>
                </item>
        
                <item>
                        <title>How much space does an 8-bit integer occupy in C and Haskell?</title>
                        <description>&lt;p&gt;How much space does an unsigned 8-bit integer occupy in C and
Haskell?&lt;/p&gt;
&lt;p&gt;Neither the C99 standard nor the Haskell2010 standard specifies such
low-level details, so the answer could in theory be anything. To have
something to work with, let’s make the following assumptions:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;architecture: x86-64&lt;/li&gt;
&lt;li&gt;ABI/calling conventions: &lt;a
href=&quot;https://software.intel.com/sites/default/files/article/402129/mpx-linux64-abi.pdf&quot;&gt;System
V&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;C compiler: GCC 6.3&lt;/li&gt;
&lt;li&gt;Haskell compiler: GHC 8.0&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;c&quot;&gt;C&lt;/h2&gt;
&lt;p&gt;In C, the unsigned 8-bit integer type is called &lt;code&gt;uint8_t&lt;/code&gt;.
It is defined in the header &lt;code&gt;stdint.h&lt;/code&gt;. Its width is
guaranteed to be exactly 8 bits; thus, its size is 1 byte.&lt;/p&gt;
&lt;p&gt;But how much space does it &lt;em&gt;really&lt;/em&gt; occupy? That depends on
two factors&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;whether it is a function argument or return value, or a (local or
global) variable&lt;/li&gt;
&lt;li&gt;whether it is part of an array or struct&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;function-arguments-and-return-values&quot;&gt;Function arguments and
return values&lt;/h3&gt;
&lt;p&gt;According to the &lt;a
href=&quot;https://software.intel.com/sites/default/files/article/402129/mpx-linux64-abi.pdf&quot;&gt;AMD64
System V ABI&lt;/a&gt;, the first 6 integer arguments are passed via registers
and the rest are passed on the stack. If a function returns a single
integer value, it is passed back in a register. Since the integer
registers are 64-bit wide, when a &lt;code&gt;uint8_t&lt;/code&gt; value is passed
in a register, it effectively occupies 8 bytes.&lt;/p&gt;
&lt;p&gt;To illustrate, consider this function:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb1&quot;&gt;&lt;pre class=&quot;sourceCode c&quot;&gt;&lt;code class=&quot;sourceCode c&quot;&gt;&lt;span id=&quot;cb1-1&quot;&gt;&lt;a href=&quot;#cb1-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;dt&quot;&gt;uint8_t&lt;/span&gt; plus&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dt&quot;&gt;uint8_t&lt;/span&gt; a&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;uint8_t&lt;/span&gt; b&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-2&quot;&gt;&lt;a href=&quot;#cb1-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;cf&quot;&gt;return&lt;/span&gt; a&lt;span class=&quot;op&quot;&gt;+&lt;/span&gt;b&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-3&quot;&gt;&lt;a href=&quot;#cb1-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;GCC generates the following code:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb2&quot;&gt;&lt;pre
class=&quot;sourceCode asm&quot;&gt;&lt;code class=&quot;sourceCode fasm&quot;&gt;&lt;span id=&quot;cb2-1&quot;&gt;&lt;a href=&quot;#cb2-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;bu&quot;&gt;lea&lt;/span&gt;    &lt;span class=&quot;op&quot;&gt;(%&lt;/span&gt;&lt;span class=&quot;kw&quot;&gt;rsi&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,%&lt;/span&gt;&lt;span class=&quot;kw&quot;&gt;rdi&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;),%&lt;/span&gt;&lt;span class=&quot;kw&quot;&gt;eax&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-2&quot;&gt;&lt;a href=&quot;#cb2-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;retq   &lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The two arguments are passed in the 64-bit registers
&lt;code&gt;%rsi&lt;/code&gt; and &lt;code&gt;%rdi&lt;/code&gt;. Although the result is written
to a 32-bit register &lt;code&gt;%eax&lt;/code&gt;, it is part of the 64-bit
register &lt;code&gt;%rax&lt;/code&gt;, and the other 32 bit of that register cannot
be reused easily while &lt;code&gt;%eax&lt;/code&gt; is occupied.&lt;/p&gt;
&lt;p&gt;What about the arguments passed through the stack? The ABI dictates
that their sizes, too, are rounded up to 8 bytes. This allows to
preserve stack alignment without complicating the calling
conventions.&lt;/p&gt;
&lt;p&gt;Example:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb3&quot;&gt;&lt;pre class=&quot;sourceCode c&quot;&gt;&lt;code class=&quot;sourceCode c&quot;&gt;&lt;span id=&quot;cb3-1&quot;&gt;&lt;a href=&quot;#cb3-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;dt&quot;&gt;uint8_t&lt;/span&gt; plus&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dt&quot;&gt;uint8_t&lt;/span&gt; a&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;uint8_t&lt;/span&gt; b&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;uint8_t&lt;/span&gt; c&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-2&quot;&gt;&lt;a href=&quot;#cb3-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;             &lt;span class=&quot;dt&quot;&gt;uint8_t&lt;/span&gt; d&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;uint8_t&lt;/span&gt; e&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;uint8_t&lt;/span&gt; f&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-3&quot;&gt;&lt;a href=&quot;#cb3-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;             &lt;span class=&quot;dt&quot;&gt;uint8_t&lt;/span&gt; g&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-4&quot;&gt;&lt;a href=&quot;#cb3-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;cf&quot;&gt;return&lt;/span&gt; a&lt;span class=&quot;op&quot;&gt;+&lt;/span&gt;g&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-5&quot;&gt;&lt;a href=&quot;#cb3-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;translates into&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb4&quot;&gt;&lt;pre
class=&quot;sourceCode asm&quot;&gt;&lt;code class=&quot;sourceCode fasm&quot;&gt;&lt;span id=&quot;cb4-1&quot;&gt;&lt;a href=&quot;#cb4-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;bu&quot;&gt;mov&lt;/span&gt;    &lt;span class=&quot;op&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;kw&quot;&gt;edi&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,%&lt;/span&gt;&lt;span class=&quot;kw&quot;&gt;eax&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-2&quot;&gt;&lt;a href=&quot;#cb4-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;bu&quot;&gt;add&lt;/span&gt;    &lt;span class=&quot;bn&quot;&gt;0x8&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(%&lt;/span&gt;&lt;span class=&quot;kw&quot;&gt;rsp&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;),%&lt;/span&gt;&lt;span class=&quot;kw&quot;&gt;al&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-3&quot;&gt;&lt;a href=&quot;#cb4-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;retq   &lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;We see that the &lt;code&gt;g&lt;/code&gt; argument is 8 bytes below the stack
boundary, &lt;code&gt;(%rsp)&lt;/code&gt;. These whole 8 bytes are dedicated to our
tiny int.&lt;/p&gt;
&lt;p&gt;When &lt;code&gt;uint8_t&lt;/code&gt;’s are part of a struct or similar, they
occupy one byte each. Curiously, if the struct is 16 bytes or smaller,
the &lt;code&gt;uint8_t&lt;/code&gt;’s will be packed into registers!&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb5&quot;&gt;&lt;pre class=&quot;sourceCode c&quot;&gt;&lt;code class=&quot;sourceCode c&quot;&gt;&lt;span id=&quot;cb5-1&quot;&gt;&lt;a href=&quot;#cb5-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;struct&lt;/span&gt; twobytes &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-2&quot;&gt;&lt;a href=&quot;#cb5-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;dt&quot;&gt;uint8_t&lt;/span&gt; a&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-3&quot;&gt;&lt;a href=&quot;#cb5-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;dt&quot;&gt;uint8_t&lt;/span&gt; b&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-4&quot;&gt;&lt;a href=&quot;#cb5-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;op&quot;&gt;};&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-5&quot;&gt;&lt;a href=&quot;#cb5-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-6&quot;&gt;&lt;a href=&quot;#cb5-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;dt&quot;&gt;uint8_t&lt;/span&gt; plus&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kw&quot;&gt;struct&lt;/span&gt; twobytes p&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-7&quot;&gt;&lt;a href=&quot;#cb5-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;cf&quot;&gt;return&lt;/span&gt; p&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;a&lt;span class=&quot;op&quot;&gt;+&lt;/span&gt;p&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;b&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-8&quot;&gt;&lt;a href=&quot;#cb5-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;compiles into&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb6&quot;&gt;&lt;pre
class=&quot;sourceCode asm&quot;&gt;&lt;code class=&quot;sourceCode fasm&quot;&gt;&lt;span id=&quot;cb6-1&quot;&gt;&lt;a href=&quot;#cb6-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;bu&quot;&gt;mov&lt;/span&gt;    &lt;span class=&quot;op&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;kw&quot;&gt;edi&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,%&lt;/span&gt;&lt;span class=&quot;kw&quot;&gt;eax&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-2&quot;&gt;&lt;a href=&quot;#cb6-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;movzbl &lt;span class=&quot;op&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;kw&quot;&gt;ah&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,%&lt;/span&gt;&lt;span class=&quot;kw&quot;&gt;eax&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-3&quot;&gt;&lt;a href=&quot;#cb6-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;bu&quot;&gt;add&lt;/span&gt;    &lt;span class=&quot;op&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;kw&quot;&gt;edi&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,%&lt;/span&gt;&lt;span class=&quot;kw&quot;&gt;eax&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-4&quot;&gt;&lt;a href=&quot;#cb6-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;retq   &lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Both bytes are passed inside &lt;code&gt;%edi&lt;/code&gt;, and the intermediate
1-byte &lt;code&gt;%ah&lt;/code&gt; register is used to take them apart.&lt;/p&gt;
&lt;h3 id=&quot;local-and-global-variables&quot;&gt;Local and global variables&lt;/h3&gt;
&lt;p&gt;Like function arguments, local variables can reside in registers or
on the stack. But unlike function arguments, local variables are not
constrained by calling conventions; the compiler can do whatever it
wants.&lt;/p&gt;
&lt;p&gt;When an 8-bit local variable is stored in a register, it effectively
occupies the whole 64-bit register, as there is only one 8-bit
“subregister” per general-purpose register (unlike in x86).&lt;/p&gt;
&lt;p&gt;What happens to the local &lt;code&gt;uint8_t&lt;/code&gt; variables stored on
the stack? We can compile this test program to find out:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb7&quot;&gt;&lt;pre class=&quot;sourceCode c&quot;&gt;&lt;code class=&quot;sourceCode c&quot;&gt;&lt;span id=&quot;cb7-1&quot;&gt;&lt;a href=&quot;#cb7-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;dt&quot;&gt;uint8_t&lt;/span&gt; plus&lt;span class=&quot;op&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dt&quot;&gt;uint8_t&lt;/span&gt; a&lt;span class=&quot;op&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;uint8_t&lt;/span&gt; b&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb7-2&quot;&gt;&lt;a href=&quot;#cb7-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;dt&quot;&gt;volatile&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;uint8_t&lt;/span&gt; c &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; a&lt;span class=&quot;op&quot;&gt;+&lt;/span&gt;b&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb7-3&quot;&gt;&lt;a href=&quot;#cb7-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;cf&quot;&gt;return&lt;/span&gt; c&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb7-4&quot;&gt;&lt;a href=&quot;#cb7-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;op&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb8&quot;&gt;&lt;pre
class=&quot;sourceCode asm&quot;&gt;&lt;code class=&quot;sourceCode fasm&quot;&gt;&lt;span id=&quot;cb8-1&quot;&gt;&lt;a href=&quot;#cb8-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;bu&quot;&gt;add&lt;/span&gt;    &lt;span class=&quot;op&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;kw&quot;&gt;edi&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;,%&lt;/span&gt;&lt;span class=&quot;kw&quot;&gt;esi&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb8-2&quot;&gt;&lt;a href=&quot;#cb8-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;bu&quot;&gt;mov&lt;/span&gt;    &lt;span class=&quot;op&quot;&gt;%&lt;/span&gt;sil&lt;span class=&quot;op&quot;&gt;,-&lt;/span&gt;&lt;span class=&quot;bn&quot;&gt;0x1&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(%&lt;/span&gt;&lt;span class=&quot;kw&quot;&gt;rsp&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb8-3&quot;&gt;&lt;a href=&quot;#cb8-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;movzbl &lt;span class=&quot;op&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;bn&quot;&gt;0x1&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;(%&lt;/span&gt;&lt;span class=&quot;kw&quot;&gt;rsp&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;),%&lt;/span&gt;&lt;span class=&quot;kw&quot;&gt;eax&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb8-4&quot;&gt;&lt;a href=&quot;#cb8-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;retq   &lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The &lt;code&gt;volatile&lt;/code&gt; keyword is needed to force the compiler to
store the local variable &lt;code&gt;c&lt;/code&gt; on the stack rather than in a
register. As we see, &lt;code&gt;c&lt;/code&gt; is stored at
&lt;code&gt;-0x1(%rsp)&lt;/code&gt;, so 1 byte is enough here. This is because there
is no alignment requirement for 8-bit integers. The same is true for
global variables.&lt;/p&gt;
&lt;h2 id=&quot;haskell&quot;&gt;Haskell&lt;/h2&gt;
&lt;p&gt;In Haskell, the unsigned 8-bit integer type is called
&lt;code&gt;Word8&lt;/code&gt;. Its canonical module &lt;a
href=&quot;https://www.haskell.org/onlinereport/haskell2010/haskellch23.html&quot;&gt;according
to the standard&lt;/a&gt; is &lt;code&gt;Data.Word&lt;/code&gt;, but in GHC, it is
originally defined in &lt;code&gt;GHC.Word&lt;/code&gt; and then re-exported from
&lt;code&gt;Data.Word&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Word8&lt;/code&gt; is a boxed type. The space occupied by every boxed
type in Haskell consists of two parts: the header and the payload. Here
is a helpful picture from the &lt;a
href=&quot;https://ghc.haskell.org/trac/ghc/wiki/Commentary/Rts/Storage/HeapObjects&quot;&gt;GHC
wiki&lt;/a&gt;:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/img/ghc-heap-object.png&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Note that stuff on the bottom of the picture — the info table and the
entry code — is read-only static data shared among all instances of the
given type and even across multiple copies of the same program, so we
don’t count it towards the space occupied by a value.&lt;/p&gt;
&lt;p&gt;The header is a structure that (on x86-64) normally consists of 8
bytes — a pointer to the entry code for the object.&lt;/p&gt;
&lt;p&gt;The value of our byte is stored in the payload. But how exactly?
Let’s look at the definition of &lt;code&gt;Word8&lt;/code&gt; in &lt;a
href=&quot;https://github.com/ghc/ghc/blob/ghc-8.0.2-release/libraries/base/GHC/Word.hs#L62-L66&quot;&gt;&lt;code&gt;GHC.Word&lt;/code&gt;&lt;/a&gt;:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb9&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb9-1&quot;&gt;&lt;a href=&quot;#cb9-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;co&quot;&gt;-- Word8 is represented in the same way as Word. Operations may assume&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb9-2&quot;&gt;&lt;a href=&quot;#cb9-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;co&quot;&gt;-- and must ensure that it holds only values from its logical range.&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb9-3&quot;&gt;&lt;a href=&quot;#cb9-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb9-4&quot;&gt;&lt;a href=&quot;#cb9-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Word8&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;W8&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;#&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Word&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;#&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb9-5&quot;&gt;&lt;a href=&quot;#cb9-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;co&quot;&gt;-- ^ 8-bit unsigned integer type&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;Word#&lt;/code&gt; is an unboxed machine-word-sized unsigned integer,
i.e. a 64-bit integer for x86-64.&lt;/p&gt;
&lt;p&gt;In total, a &lt;code&gt;Word8&lt;/code&gt; lying around occupies 16 bytes. When
computing with &lt;code&gt;Word8&lt;/code&gt;’s inside some kind of inner loop, they
will normally be unboxed into &lt;code&gt;Word#&lt;/code&gt;’s and passed around in
8-byte registers or in 8-byte cells on the (Haskell) stack — more or
less like in C.&lt;/p&gt;
&lt;p&gt;Thus, during computation, Haskell is not that different from C. But
what about storage? Can multiple &lt;code&gt;Word8&lt;/code&gt;’s be packed together
densely?&lt;/p&gt;
&lt;h3 id=&quot;twobytes&quot;&gt;TwoBytes&lt;/h3&gt;
&lt;p&gt;Say, we need a structure, &lt;code&gt;TwoBytes&lt;/code&gt;, consisting of two
&lt;code&gt;Word8&lt;/code&gt;’s. We intend to use it as a key and/or element type
in a large dictionary, so we’d like to keep it as compact as possible.
(Note that &lt;code&gt;Data.Map&lt;/code&gt; already &lt;a
href=&quot;http://blog.johantibell.com/2011/06/memory-footprints-of-some-common-data.html&quot;&gt;adds
a 48 bytes overhead per key/value&lt;/a&gt;.)&lt;/p&gt;
&lt;p&gt;If we declare &lt;code&gt;TwoBytes&lt;/code&gt; in the most naive way&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb10&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb10-1&quot;&gt;&lt;a href=&quot;#cb10-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;TwoBytes&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;TwoBytes&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Word8&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Word8&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;the structure will occupy 56 bytes! &lt;code&gt;TwoBytes&lt;/code&gt; would
consist of a header (8 bytes) and a payload consisting of two pointers
(8 bytes each), each pointing to a &lt;code&gt;Word8&lt;/code&gt; (16 bytes
each).&lt;/p&gt;
&lt;p&gt;A more efficient way to declare &lt;code&gt;TwoBytes&lt;/code&gt; is&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb11&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb11-1&quot;&gt;&lt;a href=&quot;#cb11-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;TwoBytes&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;TwoBytes&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;{-# UNPACK #-}&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;dt&quot;&gt;Word8&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb11-2&quot;&gt;&lt;a href=&quot;#cb11-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;                         &lt;span class=&quot;ot&quot;&gt;{-# UNPACK #-}&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;dt&quot;&gt;Word8&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This makes the fields strict and unpacked, so that the two bytes are
stored directly in &lt;code&gt;TwoBytes&lt;/code&gt;’s payload. This occupies 24
bytes — “only” 12 bytes per &lt;code&gt;Word8&lt;/code&gt;. Compared to a single
&lt;code&gt;Word8&lt;/code&gt;, we see some economy, but it only amortizes the
header. No matter how many &lt;code&gt;Word8&lt;/code&gt;’s we put together, the
size won’t get below 8 bytes per &lt;code&gt;Word8&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;To pack bytes together, we can use an &lt;a
href=&quot;https://hackage.haskell.org/package/vector-0.12.0.0/docs/Data-Vector-Unboxed.html&quot;&gt;unboxed
vector&lt;/a&gt;:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb12&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb12-1&quot;&gt;&lt;a href=&quot;#cb12-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;TwoBytes&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;TwoBytes&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;{-# UNPACK #-}&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;!&lt;/span&gt;(&lt;span class=&quot;dt&quot;&gt;Vector&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Word8&lt;/span&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;To see how much memory this structure occupies, we need to see the
definition of &lt;a
href=&quot;https://github.com/haskell/vector/blob/cae5e7a3f0fdb8b737bb5b07794ff8c0b4f64fe8/Data/Vector.hs#L212-L215&quot;&gt;&lt;code&gt;Vector&lt;/code&gt;&lt;/a&gt;
and the underlying &lt;a
href=&quot;https://github.com/haskell/primitive/blob/master/Data/Primitive/ByteArray.hs#L52&quot;&gt;ByteArray&lt;/a&gt;:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb13&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb13-1&quot;&gt;&lt;a href=&quot;#cb13-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;co&quot;&gt;-- | Unboxed vectors of primitive types&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb13-2&quot;&gt;&lt;a href=&quot;#cb13-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Vector&lt;/span&gt; a &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Vector&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;{-# UNPACK #-}&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;dt&quot;&gt;Int&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb13-3&quot;&gt;&lt;a href=&quot;#cb13-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;                       &lt;span class=&quot;ot&quot;&gt;{-# UNPACK #-}&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;dt&quot;&gt;Int&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb13-4&quot;&gt;&lt;a href=&quot;#cb13-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;                       &lt;span class=&quot;ot&quot;&gt;{-# UNPACK #-}&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;dt&quot;&gt;ByteArray&lt;/span&gt; &lt;span class=&quot;co&quot;&gt;-- ^ offset, length, underlying byte array&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb13-5&quot;&gt;&lt;a href=&quot;#cb13-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;ByteArray&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;ByteArray&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;ByteArray&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;#&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The runtime representation of &lt;code&gt;ByteArray#&lt;/code&gt; is a pointer to
the &lt;code&gt;StgArrBytes&lt;/code&gt; structure defined in
&lt;code&gt;includes/rts/storage/Closures.h&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb14&quot;&gt;&lt;pre class=&quot;sourceCode c&quot;&gt;&lt;code class=&quot;sourceCode c&quot;&gt;&lt;span id=&quot;cb14-1&quot;&gt;&lt;a href=&quot;#cb14-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;typedef&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb14-2&quot;&gt;&lt;a href=&quot;#cb14-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    StgHeader  header&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb14-3&quot;&gt;&lt;a href=&quot;#cb14-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    StgWord    bytes&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb14-4&quot;&gt;&lt;a href=&quot;#cb14-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    StgWord    payload&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;FLEXIBLE_ARRAY&lt;span class=&quot;op&quot;&gt;];&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb14-5&quot;&gt;&lt;a href=&quot;#cb14-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;op&quot;&gt;}&lt;/span&gt; StgArrBytes&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The space required for a &lt;code&gt;ByteArray#&lt;/code&gt; is 8 bytes for the
header, 8 bytes for the length, and the payload, rounded up to whole
words (see &lt;code&gt;stg_newByteArrayzh&lt;/code&gt; in
&lt;code&gt;rts/PrimOps.cmm&lt;/code&gt;) — so 8 bytes in our case, 24 in total.&lt;/p&gt;
&lt;p&gt;The size of &lt;code&gt;Vector&lt;/code&gt;, therefore, is 8 bytes for the
header, 16 bytes for the offset and length (needed to provide O(1)
slicing for vectors), 8 bytes for the pointer to the
&lt;code&gt;ByteArray#&lt;/code&gt;, and 24 bytes for &lt;code&gt;ByteArray#&lt;/code&gt;
itself; total of 56 bytes.&lt;/p&gt;
&lt;p&gt;This is the opposite of the previous definition in that the
representation is asymptotically efficient, requiring 1 byte per
&lt;code&gt;Word8&lt;/code&gt;, but the upfront cost makes it absolutely impractical
for &lt;code&gt;TwoBytes&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Even if we cut out the middleman and used &lt;code&gt;ByteArray&lt;/code&gt;
directly:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb15&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb15-1&quot;&gt;&lt;a href=&quot;#cb15-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;TwoBytes&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;TwoBytes&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;{-# UNPACK #-}&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;dt&quot;&gt;ByteArray&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;… it would only get us to 40 bytes.&lt;/p&gt;
&lt;p&gt;The most frugal approach for the case of two bytes is to define&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb16&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb16-1&quot;&gt;&lt;a href=&quot;#cb16-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;TwoBytes&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;TwoBytes&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;{-# UNPACK #-}&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;dt&quot;&gt;Word&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;(16 bytes) and do packing/unpacking by hand. This is a rare case
where a Haskell programmer needs to write code that a C compiler would
generate (recall two bytes packed into &lt;code&gt;%edi&lt;/code&gt;) and not the
other way around.&lt;/p&gt;
&lt;p&gt;If GHC provided a &lt;code&gt;Word8#&lt;/code&gt; unboxed type, we could use the
earlier defined&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb17&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb17-1&quot;&gt;&lt;a href=&quot;#cb17-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;TwoBytes&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;TwoBytes&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;{-# UNPACK #-}&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;dt&quot;&gt;Word8&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb17-2&quot;&gt;&lt;a href=&quot;#cb17-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;                         &lt;span class=&quot;ot&quot;&gt;{-# UNPACK #-}&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;dt&quot;&gt;Word8&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;which would still occupy 16 bytes but be more conventient to work
with than a single &lt;code&gt;Word&lt;/code&gt;. But that’d require a major change
to the compiler, and it’s probably not worth the hassle.&lt;/p&gt;
&lt;h2 id=&quot;summary&quot;&gt;Summary&lt;/h2&gt;
&lt;p&gt;In both C and Haskell, a byte-sized integer occupies 8 bytes when it
is actively worked upon (i.e. kept in a register) and 1 byte when many
of them are stored in an array/vector.&lt;/p&gt;
&lt;p&gt;However, when storing single &lt;code&gt;Word8&lt;/code&gt;’s or small structures
like &lt;code&gt;TwoBytes&lt;/code&gt;, Haskell is not as memory-efficient.
Primarily this is because idiomatic Haskell relies heavily on pointers
and everything is word-aligned.&lt;/p&gt;
</description>
                        <pubDate>Wed, 25 Jan 2017 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2017-01-25-word8-space</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2017-01-25-word8-space.html</guid>
                </item>
        
                <item>
                        <title>Getting Random Things Done: fetching a random card from Trello
</title>
                        <description>&lt;p&gt;I am a big fan of randomness. Often when I struggle with a decision,
be it what to have for lunch or how to name a baby, I pick a &lt;s&gt;magic
ball&lt;/s&gt; random number generator and do whatever it tells me.&lt;/p&gt;
&lt;p&gt;Randomness is especially helpful in deciding what to do next. This is
a decision we make many times a day, and it can consume a lot of mental
energy.&lt;/p&gt;
&lt;p&gt;In &lt;a href=&quot;http://gettingthingsdone.com/&quot;&gt;Getting things done&lt;/a&gt;,
David Allen suggests a four-criteria model for choosing actions. Four
criteria! That sounds like a lot of work in itself. Why don’t we
delegate this decision to chance?&lt;/p&gt;
&lt;p&gt;Since I use &lt;a href=&quot;https://trello.com/&quot;&gt;Trello&lt;/a&gt; as my GTD
system, I developed a simple UNIX shell script to fetch random Trello
cards from a particular list (such as “Next actions” or “To read”). If
you would like to try it out, follow the instructions below.&lt;/p&gt;
&lt;h2 id=&quot;how-to&quot;&gt;How-to&lt;/h2&gt;
&lt;p&gt;First, go to &lt;a href=&quot;https://trello.com/app-key&quot;
class=&quot;uri&quot;&gt;https://trello.com/app-key&lt;/a&gt; and copy the API key it
generates. That page also has a link to generate a token “if you are
looking to build an application for yourself” — and that’s exactly what
you are doing. So go ahead and generate a token.&lt;/p&gt;
&lt;p&gt;Save the API key and the token you’ve got to shell variables:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;TRELLO_KEY=317130d1b90d72ac17ef53d59ba1bd81
TRELLO_TOKEN=65136e476c86f3688d33440acc7ba10681c9eb756e6557e78d119e28eec8e1bc&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Next, you need to find out the id of the list you are interested in.
Even the &lt;a
href=&quot;https://developers.trello.com/get-started/start-building#create&quot;&gt;official
docs&lt;/a&gt; admit that&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;One of the trickier parts of using the Trello API for simple use
cases is finding a List ID that belongs to a user.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Follow &lt;a
href=&quot;https://developers.trello.com/get-started/start-building#create&quot;&gt;their
instructions&lt;/a&gt; to get the list id. Then create a shell variable to
hold it:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;TRELLO_LIST=a117f78b518937b5d958fcc8&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Once you have the right data in the right variables, simply run the
following pipeline in your shell prompt:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;curl -Ns &amp;quot;https://api.trello.com/1/lists/$TRELLO_LIST/cards/open?key=$TRELLO_KEY&amp;amp;token=$TRELLO_TOKEN&amp;quot; |
  jq -r &amp;#39;.[] | &amp;quot;\(.name): \(.desc)\n&amp;quot; | @base64&amp;#39; |
  shuf -n 1 |
  base64 --decode&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;(The base64 encoding/decoding is needed to handle correctly
descriptions that span multiple lines.)&lt;/p&gt;
&lt;p&gt;You can put the above commands into a file and make it an executable
script. For instance, I have scripts &lt;code&gt;random-trello-action&lt;/code&gt;
and &lt;code&gt;random-trello-paper&lt;/code&gt;.&lt;/p&gt;
</description>
                        <pubDate>Sun, 22 Jan 2017 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2017-01-22-random-trello-card</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2017-01-22-random-trello-card.html</guid>
                </item>
        
                <item>
                        <title>Nested monadic loops may cause space leaks</title>
                        <description>&lt;p&gt;Consider the following trivial Haskell program:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb1&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb1-1&quot;&gt;&lt;a href=&quot;#cb1-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;main ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;IO&lt;/span&gt; ()&lt;/span&gt;
&lt;span id=&quot;cb1-2&quot;&gt;&lt;a href=&quot;#cb1-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;main &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; worker&lt;/span&gt;
&lt;span id=&quot;cb1-3&quot;&gt;&lt;a href=&quot;#cb1-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-4&quot;&gt;&lt;a href=&quot;#cb1-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;{-# NOINLINE worker #-}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-5&quot;&gt;&lt;a href=&quot;#cb1-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;worker ::&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;Monad&lt;/span&gt; m) &lt;span class=&quot;ot&quot;&gt;=&amp;gt;&lt;/span&gt; m ()&lt;/span&gt;
&lt;span id=&quot;cb1-6&quot;&gt;&lt;a href=&quot;#cb1-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;worker &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-7&quot;&gt;&lt;a href=&quot;#cb1-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;let&lt;/span&gt; loop &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; poll &lt;span class=&quot;op&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt; loop&lt;/span&gt;
&lt;span id=&quot;cb1-8&quot;&gt;&lt;a href=&quot;#cb1-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;in&lt;/span&gt; loop&lt;/span&gt;
&lt;span id=&quot;cb1-9&quot;&gt;&lt;a href=&quot;#cb1-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-10&quot;&gt;&lt;a href=&quot;#cb1-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;poll ::&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;Monad&lt;/span&gt; m) &lt;span class=&quot;ot&quot;&gt;=&amp;gt;&lt;/span&gt; m a&lt;/span&gt;
&lt;span id=&quot;cb1-11&quot;&gt;&lt;a href=&quot;#cb1-11&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;poll &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;return&lt;/span&gt; () &lt;span class=&quot;op&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt; poll&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;It doesn’t do much — except, as it turns out, eat a lot of
memory!&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% ./test +RTS -s &amp;amp; sleep 1s &amp;amp;&amp;amp; kill -SIGINT %1
     751,551,192 bytes allocated in the heap                                               
   1,359,059,768 bytes copied during GC
     450,901,152 bytes maximum residency (11 sample(s))
       7,166,816 bytes maximum slop
             888 MB total memory in use (0 MB lost due to fragmentation)

                                     Tot time (elapsed)  Avg pause  Max pause
  Gen  0      1429 colls,     0 par    0.265s   0.265s     0.0002s    0.0005s
  Gen  1        11 colls,     0 par    0.701s   0.703s     0.0639s    0.3266s

  INIT    time    0.000s  (  0.000s elapsed)
  MUT     time    0.218s  (  0.218s elapsed)
  GC      time    0.966s  (  0.968s elapsed)
  EXIT    time    0.036s  (  0.036s elapsed)
  Total   time    1.223s  (  1.222s elapsed)

  %GC     time      79.0%  (79.2% elapsed)

  Alloc rate    3,450,267,071 bytes per MUT second

  Productivity  21.0% of total user, 21.0% of total elapsed&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;These nested loops happen often in server-side programming. About a
year ago, when I worked for Signal Vine, &lt;a
href=&quot;https://github.com/michaelt/streaming/issues/6&quot;&gt;this happened to
my code&lt;/a&gt;: the inner loop was a big streaming computation; the outer
loop was something that would restart the inner loop should it fail.&lt;/p&gt;
&lt;p&gt;Later that year, &lt;a
href=&quot;https://www.well-typed.com/blog/2016/09/sharing-conduit/&quot;&gt;Edsko de
Vries blogged about a very similar issue&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Recently, &lt;a href=&quot;http://stackoverflow.com/q/41306593/110081&quot;&gt;Sean
Clark Hess observed something similar&lt;/a&gt;. In his case, the inner loop
waits for a particular AMQP message, and the outer loop calls the inner
loop repeatedly to extract all such messages.&lt;/p&gt;
&lt;p&gt;So why would such an innocent-looking piece of code consume unbounded
amounts of memory? To find out, let’s trace the program execution on the
STG level.&lt;/p&gt;
&lt;h2 id=&quot;background-stg-and-io&quot;&gt;Background: STG and IO&lt;/h2&gt;
&lt;p&gt;The runtime model of ghc-compiled programs is described in the paper
&lt;a
href=&quot;http://community.haskell.org/~simonmar/papers/evalapplyjfp06.pdf&quot;&gt;Making
a Fast Curry: Push/Enter vs. Eval/Apply for Higher-order Languages&lt;/a&gt;.
Here is the grammar and the reduction rules for the quick reference.&lt;/p&gt;
&lt;figure&gt;
&lt;p&gt;&lt;img src=&quot;/img/eval_apply_grammar.png&quot; /&gt; &lt;img
src=&quot;/img/eval_apply_semantics1.png&quot; /&gt; &lt;img
src=&quot;/img/eval_apply_semantics2.png&quot; /&gt;&lt;/p&gt;
&lt;/figure&gt;
&lt;p&gt;It is going to be important that the &lt;code&gt;IO&lt;/code&gt; type in GHC is a
function type:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;newtype IO a = IO (State# RealWorld -&amp;gt; (# State# RealWorld, a #))&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here are a few good introductions to the internals of
&lt;code&gt;IO&lt;/code&gt;: from &lt;a
href=&quot;https://www.well-typed.com/blog/2014/06/understanding-the-realworld/&quot;&gt;Edsko
de Vries&lt;/a&gt;, &lt;a
href=&quot;http://blog.ezyang.com/2011/05/unraveling-the-mystery-of-the-io-monad/&quot;&gt;Edward
Z. Yang&lt;/a&gt;, and &lt;a
href=&quot;https://www.fpcomplete.com/blog/2015/02/primitive-haskell&quot;&gt;Michael
Snoyman&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;our-program-in-stg&quot;&gt;Our program in STG&lt;/h2&gt;
&lt;p&gt;Let’s see now how our program translates to STG. This is a
translation done by ghc 8.0.1 with
&lt;code&gt;-O -ddump-stg -dsuppress-all&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;poll_rnN =
    sat-only \r srt:SRT:[] [$dMonad_s312]
        let { sat_s314 = \u srt:SRT:[] [] poll_rnN $dMonad_s312; } in
        let { sat_s313 = \u srt:SRT:[] [] return $dMonad_s312 ();
        } in  &amp;gt;&amp;gt; $dMonad_s312 sat_s313 sat_s314;

worker =
    \r srt:SRT:[] [$dMonad_s315]
        let {
          loop_s316 =
              \u srt:SRT:[] []
                  let { sat_s317 = \u srt:SRT:[] [] poll_rnN $dMonad_s315;
                  } in  &amp;gt;&amp;gt; $dMonad_s315 sat_s317 loop_s316;
        } in  loop_s316;

main = \u srt:SRT:[r2 :-&amp;gt; $fMonadIO] [] worker $fMonadIO;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is the STG as understood by ghc itself. In the notation of the
fast curry paper introduced above, this (roughly) translates to:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;main = THUNK(worker monadIO realWorld);

worker = FUN(monad -&amp;gt;
  let {
    loop = THUNK(let {worker_poll_thunk = THUNK(poll monad);}
                 in then monad worker_poll_thunk loop);
  } in loop
);

poll = FUN(monad -&amp;gt;
  let {
    ret_thunk = THUNK(return monad unit);
    poll_poll_thunk = THUNK(poll monad);
  }
  in then monad ret_thunk poll_poll_thunk
);&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;monadIO&lt;/code&gt; is the record (“dictionary”) that contains the
Monad methods &lt;code&gt;&amp;gt;&amp;gt;=&lt;/code&gt;, &lt;code&gt;&amp;gt;&amp;gt;&lt;/code&gt;, and
&lt;code&gt;return&lt;/code&gt; for the IO type. We will need &lt;code&gt;return&lt;/code&gt;
and &lt;code&gt;&amp;gt;&amp;gt;&lt;/code&gt; (called &lt;code&gt;then&lt;/code&gt; here) in particular;
here is how they are defined:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;returnIO = FUN(x s -&amp;gt; (# s, x #));
thenIO = FUN(m k s -&amp;gt;
  case m s of {
    (# new_s, result #) -&amp;gt; k new_s
  }
);
monadIO = CON(Monad returnIO thenIO);
return = FUN(monad -&amp;gt;
  case monad of {
    Monad return then -&amp;gt; return
  }
);
then = FUN(monad -&amp;gt;
  case monad of {
    Monad return then -&amp;gt; then
  }
);&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;stg-interpreters&quot;&gt;STG interpreters&lt;/h2&gt;
&lt;p&gt;We could run our STG program by hand following the reduction rules
listed above. If you have never done it, I highly recommend performing
several reductions by hand as an exercise. But it is a bit tedious and
error-prone. That’s why we will use &lt;a
href=&quot;http://berniepope.id.au/&quot;&gt;Bernie Pope&lt;/a&gt;’s &lt;a
href=&quot;https://wiki.haskell.org/Ministg&quot;&gt;Ministg&lt;/a&gt; interpreter. &lt;a
href=&quot;https://github.com/UnkindPartition/ministg&quot;&gt;My fork&lt;/a&gt; of Ministg
adds support for unboxed tuples and recursive let bindings necessary to
run our program.&lt;/p&gt;
&lt;p&gt;There is another STG interpreter, &lt;a
href=&quot;https://github.com/quchen/stgi&quot;&gt;stgi&lt;/a&gt;, by David Luposchainsky.
It is more recent and looks nicer, but it doesn’t support the eval/apply
execution model used by ghc, which is a deal breaker for our
purposes.&lt;/p&gt;
&lt;p&gt;We run Ministg like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ministg --noprelude --trace --maxsteps=100 --style=EA --tracedir leak.trace &lt;a href=&quot;/files/2017-01-10-nested-loop-space-leak/leak.stg&quot;&gt;leak.stg&lt;/a&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Ministg will print an error message saying that the program hasn’t
finished running in 100 steps — as we would expect, — and it will also
generate a directory &lt;code&gt;leak.trace&lt;/code&gt; containing html files. Each
html file shows the state of the STG machine after a single evaluation
step. You can browse these files &lt;a
href=&quot;/files/2017-01-10-nested-loop-space-leak/leak.trace&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;tracing-the-program&quot;&gt;Tracing the program&lt;/h2&gt;
&lt;p&gt;Steps &lt;a
href=&quot;/files/2017-01-10-nested-loop-space-leak/leak.trace/step0.html&quot;&gt;0&lt;/a&gt;
through &lt;a
href=&quot;/files/2017-01-10-nested-loop-space-leak/leak.trace/step16.html&quot;&gt;16&lt;/a&gt;
take us from &lt;code&gt;main&lt;/code&gt; to &lt;code&gt;poll monadIO&lt;/code&gt;, which is
where things get interesting, because from this point on, only code
inside &lt;code&gt;poll&lt;/code&gt; will be executing. Remember, &lt;code&gt;poll&lt;/code&gt;
is an infinite loop, so it won’t give a chance for &lt;code&gt;worker&lt;/code&gt;
to run ever again.&lt;/p&gt;
&lt;p&gt;Each iteration of the &lt;code&gt;poll&lt;/code&gt; loop consists of two phases.
During the first phase, &lt;code&gt;poll monadIO&lt;/code&gt; is evaluated. This is
the “pure” part. No IO gets done during this part; we are just figuring
out &lt;em&gt;what&lt;/em&gt; is going to be executed. The first phase runs up until
&lt;a
href=&quot;/files/2017-01-10-nested-loop-space-leak/leak.trace/step24.html&quot;&gt;step
24&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;On &lt;a
href=&quot;/files/2017-01-10-nested-loop-space-leak/leak.trace/step25.html&quot;&gt;step
25&lt;/a&gt;, we grab the RealWorld token from the stack, and the second phase
— the IO phase — begins. It ends on &lt;a
href=&quot;/files/2017-01-10-nested-loop-space-leak/leak.trace/step42.html&quot;&gt;step
42&lt;/a&gt;, when the next iteration of the loop begins with
&lt;code&gt;poll monadIO&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Let’s look at the first phase in more detail. In steps &lt;a
href=&quot;/files/2017-01-10-nested-loop-space-leak/leak.trace/step18.html&quot;&gt;18&lt;/a&gt;
and &lt;a
href=&quot;/files/2017-01-10-nested-loop-space-leak/leak.trace/step19.html&quot;&gt;19&lt;/a&gt;,
the let-expression&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;let {
  ret_thunk = THUNK(return monad unit);
  poll_poll_thunk = THUNK(poll monad);
}
in then monad ret_thunk poll_poll_thunk&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;is evaluated. The thunks &lt;code&gt;ret_thunk&lt;/code&gt; and
&lt;code&gt;poll_poll_thunk&lt;/code&gt; are allocated on the heap at addresses
&lt;code&gt;$3&lt;/code&gt; and &lt;code&gt;$4&lt;/code&gt;, respectively.&lt;/p&gt;
&lt;p&gt;Later these thunks will be evaluated/updated to partial applications:
&lt;code&gt;$3=PAP(returnIO unit)&lt;/code&gt; on &lt;a
href=&quot;/files/2017-01-10-nested-loop-space-leak/leak.trace/step35.html&quot;&gt;step
35&lt;/a&gt; and &lt;code&gt;$4=PAP(thenIO $7 $8)&lt;/code&gt; on &lt;a
href=&quot;/files/2017-01-10-nested-loop-space-leak/leak.trace/step50.html&quot;&gt;step
50&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;We would hope that these partial applications will eventually be
garbage-collected. Unfortunately, not. The partial application
&lt;code&gt;$1=PAP(thenIO $3 $4)&lt;/code&gt; is defined in terms of &lt;code&gt;$3&lt;/code&gt;
and &lt;code&gt;$4&lt;/code&gt;. &lt;code&gt;$1&lt;/code&gt; is the
&lt;code&gt;worker_poll_thunk&lt;/code&gt;, the “next” instance of the
&lt;code&gt;poll&lt;/code&gt; loop invoked by &lt;code&gt;worker&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;This is why the leak doesn’t occur if there’s no outer loop. Nothing
would reference &lt;code&gt;$3&lt;/code&gt; and &lt;code&gt;$4&lt;/code&gt;, and they would be
executed and gc’d.&lt;/p&gt;
&lt;h2 id=&quot;io-that-doesnt-leak&quot;&gt;IO that doesn’t leak&lt;/h2&gt;
&lt;p&gt;The memory leak is a combination of two reasons. As we discussed
above, the first reason is the outer loop that holds on to the reference
to the inner loop.&lt;/p&gt;
&lt;p&gt;The second reason is that IO happens here in two phases: the pure
phase, during which we “compute” the IO action, and the second phase,
during which we run the computed action. If there was no first phase,
there would be nothing to remember.&lt;/p&gt;
&lt;p&gt;Consider this version of the nested loop. Here, I moved NOINLINE to
poll. (NOINLINE is needed because otherwise ghc would realize that our
program doesn’t do anything and would simplify it down to a single
infinite loop.)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;main :: IO ()
main = worker

worker :: (Monad m) =&amp;gt; m ()
worker =
  let loop = poll &amp;gt;&amp;gt; loop
  in loop

{-# NOINLINE poll #-}
poll :: (Monad m) =&amp;gt; m a
poll = return () &amp;gt;&amp;gt; poll&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In this version, ghc would inline &lt;code&gt;worker&lt;/code&gt; into main and
specialize it to &lt;code&gt;IO&lt;/code&gt;. Here is the ghc’s STG code:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;poll_rqk =
    sat-only \r srt:SRT:[] [$dMonad_s322]
        let { sat_s324 = \u srt:SRT:[] [] poll_rqk $dMonad_s322; } in
        let { sat_s323 = \u srt:SRT:[] [] return $dMonad_s322 ();
        } in  &amp;gt;&amp;gt; $dMonad_s322 sat_s323 sat_s324;

main1 =
    \r srt:SRT:[r3 :-&amp;gt; main1, r54 :-&amp;gt; $fMonadIO] [s_s325]
        case poll_rqk $fMonadIO s_s325 of _ {
          (#,#) ipv_s327 _ -&amp;gt; main1 ipv_s327;
        };&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here, &lt;code&gt;poll&lt;/code&gt; still runs in two phases, but
&lt;code&gt;main1&lt;/code&gt; (the outer loop) doesn’t. This program still
allocates memory and runs not as efficient as it could, but at least it
runs in constant memory. This is because the compiler realizes that
&lt;code&gt;poll_rqk $fMonadIO&lt;/code&gt; is not computing anything useful and
there’s no point in caching that value. (I am actually curious what
exactly ghc’s logic is here.)&lt;/p&gt;
&lt;p&gt;What if we push NOINLINE even further down?&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;main :: IO ()
main = worker

worker :: (Monad m) =&amp;gt; m ()
worker =
  let loop = poll &amp;gt;&amp;gt; loop
  in loop

poll :: (Monad m) =&amp;gt; m a
poll = do_stuff &amp;gt;&amp;gt; poll

{-# NOINLINE do_stuff #-}
do_stuff :: Monad m =&amp;gt; m ()
do_stuff = return ()&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;STG:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;do_stuff_rql =
    sat-only \r srt:SRT:[] [$dMonad_s32i] return $dMonad_s32i ();

$spoll_r2SR =
    sat-only \r srt:SRT:[r54 :-&amp;gt; $fMonadIO,
                         r2SR :-&amp;gt; $spoll_r2SR] [s_s32j]
        case do_stuff_rql $fMonadIO s_s32j of _ {
          (#,#) ipv_s32l _ -&amp;gt; $spoll_r2SR ipv_s32l;
        };

main1 =
    \r srt:SRT:[r3 :-&amp;gt; main1, r2SR :-&amp;gt; $spoll_r2SR] [s_s32n]
        case $spoll_r2SR s_s32n of _ {
          (#,#) ipv_s32p _ -&amp;gt; main1 ipv_s32p;
        };&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This code runs very efficiently, in a single phase, and doesn’t
allocate at all.&lt;/p&gt;
&lt;p&gt;Of course, in practice we wouldn’t deliberately put these NOINLINEs
in our code just to make it inefficient. Instead, the inlining or
specialization will fail to happen because the function is too big
and/or resides in a different module, or for some other reason.&lt;/p&gt;
&lt;h2 id=&quot;arities&quot;&gt;Arities&lt;/h2&gt;
&lt;p&gt;Arities provide an important perspective on the two-phase computation
issue. The arity of &lt;code&gt;then&lt;/code&gt; is 1: it is just a record
selector. The arity of &lt;code&gt;thenIO&lt;/code&gt; is 3: it takes the two
monadic values and the RealWorld state token.&lt;/p&gt;
&lt;p&gt;Arities influence what happens at runtime, as can be seen from the
STG reduction rules. Because &lt;code&gt;thenIO&lt;/code&gt; has arity 3, a partial
application is created for
&lt;code&gt;thenIO ret_thunk poll_poll_thunk&lt;/code&gt;. Let’s change the arity of
&lt;code&gt;thenIO&lt;/code&gt; to 2, so that no PAPs get created:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;thenIO = FUN(m k -&amp;gt;
  case m realWorld of {
    (# new_s, result #) -&amp;gt; k
  }
);&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;(this is similar to how &lt;code&gt;unsafePerformIO&lt;/code&gt; works). Now we
no longer have PAPs, but our heap is filled with the same exact number
of BLACKHOLEs.&lt;/p&gt;
&lt;p&gt;More importantly, arities also influence what happens during compile
time: what shape the generated STG code has. Because &lt;code&gt;then&lt;/code&gt;
has arity 1, ghc decides to create a chain of &lt;code&gt;then&lt;/code&gt;s before
passing the RealWorld token. Let’s change (“eta-expand”) the
&lt;code&gt;poll&lt;/code&gt; code &lt;em&gt;as if&lt;/em&gt; &lt;code&gt;then&lt;/code&gt; had arity 4,
without actually changing &lt;code&gt;then&lt;/code&gt; or &lt;code&gt;thenIO&lt;/code&gt; or
their runtime arities:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# added a dummy argument s
poll = FUN(monad s -&amp;gt;
  let {
    ret_thunk = THUNK(return monad unit);
    poll_poll_thunk = THUNK(poll monad);
  }
  in then monad ret_thunk poll_poll_thunk s
);
# no change in then or thenIO
then = FUN(monad -&amp;gt;
  case monad of {
    Monad return then -&amp;gt; then
  }
);
thenIO = FUN(m k s -&amp;gt;
  case m s of {
    (# new_s, result #) -&amp;gt; k new_s
  }
);&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This code now runs in constant memory!&lt;/p&gt;
&lt;p&gt;Therefore, what inlining/specialization does is that it lets the
compiler to see the &lt;em&gt;true&lt;/em&gt; arity of a function such as
&lt;code&gt;then&lt;/code&gt;. (Of course, it would also allow the compiler to
replace &lt;code&gt;then&lt;/code&gt; with &lt;code&gt;thenIO&lt;/code&gt;.)&lt;/p&gt;
&lt;h2 id=&quot;conclusions&quot;&gt;Conclusions&lt;/h2&gt;
&lt;p&gt;Let me tell you how you can avoid any such space leaks in your code
by following a simple rule:&lt;/p&gt;
&lt;p&gt;I don’t know.&lt;/p&gt;
&lt;p&gt;In some cases, &lt;a
href=&quot;https://www.well-typed.com/blog/2016/09/sharing-conduit/&quot;&gt;&lt;code&gt;-fno-full-laziness&lt;/code&gt;
or &lt;code&gt;-fno-state-hack&lt;/code&gt; help&lt;/a&gt;. In this case, they don’t.&lt;/p&gt;
&lt;p&gt;In 2012, I wrote &lt;a
href=&quot;https://ro-che.info/articles/2012-04-08-space-usage-reasoning&quot;&gt;why
reasoning about space usage in Haskell is hard&lt;/a&gt;. I don’t think
anything has changed since then. It is a hard problem to solve. I filed
a &lt;a href=&quot;https://ghc.haskell.org/trac/ghc/ticket/13080&quot;&gt;ghc bug
#13080&lt;/a&gt; just in case the ghc developers might figure out a way how to
address this particular issue.&lt;/p&gt;
&lt;p&gt;Most of the time everything works great, but once in a while you
stumble upon something like this. Such is life.&lt;/p&gt;
&lt;p&gt;Thanks to Reid Barton for pointing out that my &lt;a
href=&quot;https://stackoverflow.com/revisions/41521876/3&quot;&gt;original
theory&lt;/a&gt; regarding this leak was incomplete at best.&lt;/p&gt;
</description>
                        <pubDate>Tue, 10 Jan 2017 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2017-01-10-nested-loop-space-leak</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2017-01-10-nested-loop-space-leak.html</guid>
                </item>
        
                <item>
                        <title>optparse-applicative quick start</title>
                        <description>&lt;p&gt;When I need to write a command-line program in Haskell, I invariably
pick Paolo Capriotti’s &lt;a
href=&quot;https://github.com/pcapriotti/optparse-applicative&quot;&gt;optparse-applicative&lt;/a&gt;
library.&lt;/p&gt;
&lt;p&gt;Unfortunately, the minimal working example is complicated enough that
I cannot reproduce it from memory, and the example in the README is very
different from the style I prefer.&lt;/p&gt;
&lt;p&gt;So I decided to put up a template here for a program using
optparse-applicative. I am going to copy it into all of my future
projects, and you are welcome to do so, too.&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb1&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb1-1&quot;&gt;&lt;a href=&quot;#cb1-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Options.Applicative&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-2&quot;&gt;&lt;a href=&quot;#cb1-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Control.Monad&lt;/span&gt; (join)&lt;/span&gt;
&lt;span id=&quot;cb1-3&quot;&gt;&lt;a href=&quot;#cb1-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-4&quot;&gt;&lt;a href=&quot;#cb1-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;main ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;IO&lt;/span&gt; ()&lt;/span&gt;
&lt;span id=&quot;cb1-5&quot;&gt;&lt;a href=&quot;#cb1-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;main &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; join &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt; customExecParser (prefs showHelpOnError) &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-6&quot;&gt;&lt;a href=&quot;#cb1-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  info (helper &lt;span class=&quot;op&quot;&gt;&amp;lt;*&amp;gt;&lt;/span&gt; parser)&lt;/span&gt;
&lt;span id=&quot;cb1-7&quot;&gt;&lt;a href=&quot;#cb1-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  (  fullDesc&lt;/span&gt;
&lt;span id=&quot;cb1-8&quot;&gt;&lt;a href=&quot;#cb1-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;op&quot;&gt;&amp;lt;&amp;gt;&lt;/span&gt; header &lt;span class=&quot;st&quot;&gt;&amp;quot;General program title/description&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-9&quot;&gt;&lt;a href=&quot;#cb1-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;op&quot;&gt;&amp;lt;&amp;gt;&lt;/span&gt; progDesc &lt;span class=&quot;st&quot;&gt;&amp;quot;What does this thing do?&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-10&quot;&gt;&lt;a href=&quot;#cb1-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  )&lt;/span&gt;
&lt;span id=&quot;cb1-11&quot;&gt;&lt;a href=&quot;#cb1-11&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-12&quot;&gt;&lt;a href=&quot;#cb1-12&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;    parser ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Parser&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;IO&lt;/span&gt; ())&lt;/span&gt;
&lt;span id=&quot;cb1-13&quot;&gt;&lt;a href=&quot;#cb1-13&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    parser &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-14&quot;&gt;&lt;a href=&quot;#cb1-14&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      work&lt;/span&gt;
&lt;span id=&quot;cb1-15&quot;&gt;&lt;a href=&quot;#cb1-15&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;        &lt;span class=&quot;op&quot;&gt;&amp;lt;$&amp;gt;&lt;/span&gt; strOption&lt;/span&gt;
&lt;span id=&quot;cb1-16&quot;&gt;&lt;a href=&quot;#cb1-16&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;            (  long &lt;span class=&quot;st&quot;&gt;&amp;quot;string_param&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-17&quot;&gt;&lt;a href=&quot;#cb1-17&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;            &lt;span class=&quot;op&quot;&gt;&amp;lt;&amp;gt;&lt;/span&gt; short &lt;span class=&quot;ch&quot;&gt;&amp;#39;s&amp;#39;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-18&quot;&gt;&lt;a href=&quot;#cb1-18&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;            &lt;span class=&quot;op&quot;&gt;&amp;lt;&amp;gt;&lt;/span&gt; metavar &lt;span class=&quot;st&quot;&gt;&amp;quot;STRING&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-19&quot;&gt;&lt;a href=&quot;#cb1-19&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;            &lt;span class=&quot;op&quot;&gt;&amp;lt;&amp;gt;&lt;/span&gt; help &lt;span class=&quot;st&quot;&gt;&amp;quot;string parameter&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-20&quot;&gt;&lt;a href=&quot;#cb1-20&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;            )&lt;/span&gt;
&lt;span id=&quot;cb1-21&quot;&gt;&lt;a href=&quot;#cb1-21&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;        &lt;span class=&quot;op&quot;&gt;&amp;lt;*&amp;gt;&lt;/span&gt; option auto&lt;/span&gt;
&lt;span id=&quot;cb1-22&quot;&gt;&lt;a href=&quot;#cb1-22&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;            (  long &lt;span class=&quot;st&quot;&gt;&amp;quot;number_param&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-23&quot;&gt;&lt;a href=&quot;#cb1-23&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;            &lt;span class=&quot;op&quot;&gt;&amp;lt;&amp;gt;&lt;/span&gt; short &lt;span class=&quot;ch&quot;&gt;&amp;#39;n&amp;#39;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-24&quot;&gt;&lt;a href=&quot;#cb1-24&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;            &lt;span class=&quot;op&quot;&gt;&amp;lt;&amp;gt;&lt;/span&gt; metavar &lt;span class=&quot;st&quot;&gt;&amp;quot;NUMBER&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-25&quot;&gt;&lt;a href=&quot;#cb1-25&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;            &lt;span class=&quot;op&quot;&gt;&amp;lt;&amp;gt;&lt;/span&gt; help &lt;span class=&quot;st&quot;&gt;&amp;quot;number parameter&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-26&quot;&gt;&lt;a href=&quot;#cb1-26&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;            &lt;span class=&quot;op&quot;&gt;&amp;lt;&amp;gt;&lt;/span&gt; value &lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-27&quot;&gt;&lt;a href=&quot;#cb1-27&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;            &lt;span class=&quot;op&quot;&gt;&amp;lt;&amp;gt;&lt;/span&gt; showDefault&lt;/span&gt;
&lt;span id=&quot;cb1-28&quot;&gt;&lt;a href=&quot;#cb1-28&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;            )&lt;/span&gt;
&lt;span id=&quot;cb1-29&quot;&gt;&lt;a href=&quot;#cb1-29&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-30&quot;&gt;&lt;a href=&quot;#cb1-30&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;work ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Int&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;IO&lt;/span&gt; ()&lt;/span&gt;
&lt;span id=&quot;cb1-31&quot;&gt;&lt;a href=&quot;#cb1-31&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;work _ _ &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;return&lt;/span&gt; ()&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
</description>
                        <pubDate>Fri, 30 Dec 2016 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2016-12-30-optparse-applicative-quick-start</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2016-12-30-optparse-applicative-quick-start.html</guid>
                </item>
        
                <item>
                        <title>Matching country names by local alignment</title>
                        <description>&lt;p&gt;The other day, I was looking at the &lt;a
href=&quot;https://www.kaggle.com/START-UMD/gtd&quot;&gt;Global Terrorism
Database&lt;/a&gt; published on Kaggle. I wanted to see if the number of
terrorist attacks across countries correlated with the population of
those countries. The dataset itself didn’t contain the population
figures, so I downloaded The World Bank’s &lt;a
href=&quot;http://data.worldbank.org/indicator/SP.POP.TOTL&quot;&gt;population
data&lt;/a&gt; and tried to merge the two datasets together.&lt;/p&gt;
&lt;p&gt;Integrating datasets from different providers is rarely easy. In this
case, there were two issues:&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;&lt;p&gt;The terrorism database gives data about historic countries, while
the World Bank maps everything to modern countries.&lt;/p&gt;
&lt;p&gt;The terrorism database tells you about the terror acts performed in
the Soviet Union in 1978 or Czechoslovakia in 1972, but the World Bank
won’t tell you how many people lived in those countries. Instead, it
will tell you how many people lived in what today are Russia, Ukraine,
Czech Republic, or Slovakia.&lt;/p&gt;
&lt;p&gt;It might be possible to match modern countries and historic ones
(e.g. calculate the population of the Soviet Union by adding up the
population of all Soviet republics), but I was more interested in modern
trends, so I decided to ignore the historic countries.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Some of the modern countries have different spellings. A country
may have a common name (Russia, Macedonia) and a formal compound name
(the Russian Federation, the former Yugoslav Republic of Macedonia). The
terrorism database uses the common names, whereas the World Bank uses
the formal names, often with idiosyncratic abbreviations, such as
“Macedonia, FYR”.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;In this article, I compare several methods of matching alternative
country spellings. The winner turns out to be local alignment — a method
well known in bioinformatics but for some reason rarely used outside of
it.&lt;/p&gt;
&lt;h2 id=&quot;fuzzy-join&quot;&gt;Fuzzy join&lt;/h2&gt;
&lt;p&gt;Merging datasets based on ill-defined textual values is such a common
task that there is a special R package for it, &lt;a
href=&quot;https://github.com/dgrtwo/fuzzyjoin&quot;&gt;fuzzyjoin&lt;/a&gt;. The fuzzyjoin
package treats strings as equal if the distance between them is within a
user-specified limit. The string distance can be calculated in &lt;a
href=&quot;http://finzi.psych.upenn.edu/library/stringdist/html/stringdist-metrics.html&quot;&gt;ten
different ways&lt;/a&gt; by the &lt;a
href=&quot;https://github.com/markvanderloo/stringdist&quot;&gt;stringdist&lt;/a&gt;
package.&lt;/p&gt;
&lt;p&gt;For the task at hand, we will not use fuzzyjoin. fuzzyjoin’s mode of
operation is to have a fixed similarity threshold and treat
&lt;em&gt;everything&lt;/em&gt; similar enough as equal. Whatever distance limit we
pick, for some names it will be too tight and there won’t be a single
match, and for other names it will be too lax and we will get more than
one match.&lt;/p&gt;
&lt;p&gt;It makes sense to expect exactly one matching country in the World
Bank data for each country from the Global Terrorism Database. So
instead of picking an arbitrary threshold, for every country in the
first dataset we will pick the best matching name from the second
one.&lt;/p&gt;
&lt;h2 id=&quot;distance-based-methods&quot;&gt;Distance-based methods&lt;/h2&gt;
&lt;p&gt;Which of the 10 string distance metrics should we use to match
country names? First, I tried the classic &lt;a
href=&quot;https://en.wikipedia.org/wiki/Levenshtein_distance&quot;&gt;Levenshtein
distance&lt;/a&gt; and a couple of others metrics offered by stringdist. They
could guess some of the countries but not that many. In order to compare
the performance of different metrics, I had to compile the reference
table of true matches. (I used the algorithm’s output as a starting
point, so it wasn’t too much work.)&lt;/p&gt;
&lt;table&gt;
&lt;tr&gt;
&lt;th&gt;
Global Terrorism Database
&lt;/th&gt;
&lt;th&gt;
World Bank
&lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
Venezuela
&lt;/td&gt;
&lt;td&gt;
Venezuela, RB
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
Egypt
&lt;/td&gt;
&lt;td&gt;
Egypt, Arab Rep. 
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
Iran
&lt;/td&gt;
&lt;td&gt;
Iran, Islamic Rep. 
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
West Bank and Gaza Strip
&lt;/td&gt;
&lt;td&gt;
West Bank and Gaza
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
Syria
&lt;/td&gt;
&lt;td&gt;
Syrian Arab Republic
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
South Korea
&lt;/td&gt;
&lt;td&gt;
Korea, Rep. 
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
Bahamas
&lt;/td&gt;
&lt;td&gt;
Bahamas, The
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
Hong Kong
&lt;/td&gt;
&lt;td&gt;
Hong Kong SAR, China
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
Laos
&lt;/td&gt;
&lt;td&gt;
Lao PDR
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
Republic of the Congo
&lt;/td&gt;
&lt;td&gt;
Congo, Rep. 
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
Yemen
&lt;/td&gt;
&lt;td&gt;
Yemen, Rep. 
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
Russia
&lt;/td&gt;
&lt;td&gt;
Russian Federation
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
Ivory Coast
&lt;/td&gt;
&lt;td&gt;
Cote d’Ivoire
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
Bosnia-Herzegovina
&lt;/td&gt;
&lt;td&gt;
Bosnia and Herzegovina
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
Brunei
&lt;/td&gt;
&lt;td&gt;
Brunei Darussalam
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
Macedonia
&lt;/td&gt;
&lt;td&gt;
Macedonia, FYR
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
Gambia
&lt;/td&gt;
&lt;td&gt;
Gambia, The
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
North Korea
&lt;/td&gt;
&lt;td&gt;
Korea, Dem. People’s Rep. 
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
Macau
&lt;/td&gt;
&lt;td&gt;
Macao SAR, China
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
Kyrgyzstan
&lt;/td&gt;
&lt;td&gt;
Kyrgyz Republic
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
Democratic Republic of the Congo
&lt;/td&gt;
&lt;td&gt;
Congo, Dem. Rep. 
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
East Timor
&lt;/td&gt;
&lt;td&gt;
Timor-Leste
&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;p&gt;Now let’s see how well each metric from stringdist can reconstruct
the truth.&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb1&quot;&gt;&lt;pre class=&quot;sourceCode r&quot;&gt;&lt;code class=&quot;sourceCode r&quot;&gt;&lt;span id=&quot;cb1-1&quot;&gt;&lt;a href=&quot;#cb1-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;methods &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;c&lt;/span&gt;(&lt;span class=&quot;st&quot;&gt;&amp;quot;osa&amp;quot;&lt;/span&gt;, &lt;span class=&quot;st&quot;&gt;&amp;quot;lv&amp;quot;&lt;/span&gt;, &lt;span class=&quot;st&quot;&gt;&amp;quot;dl&amp;quot;&lt;/span&gt;, &lt;span class=&quot;st&quot;&gt;&amp;quot;hamming&amp;quot;&lt;/span&gt;, &lt;span class=&quot;st&quot;&gt;&amp;quot;lcs&amp;quot;&lt;/span&gt;, &lt;span class=&quot;st&quot;&gt;&amp;quot;qgram&amp;quot;&lt;/span&gt;, &lt;span class=&quot;st&quot;&gt;&amp;quot;cosine&amp;quot;&lt;/span&gt;, &lt;span class=&quot;st&quot;&gt;&amp;quot;jaccard&amp;quot;&lt;/span&gt;, &lt;span class=&quot;st&quot;&gt;&amp;quot;jw&amp;quot;&lt;/span&gt;, &lt;span class=&quot;st&quot;&gt;&amp;quot;soundex&amp;quot;&lt;/span&gt;)&lt;/span&gt;
&lt;span id=&quot;cb1-2&quot;&gt;&lt;a href=&quot;#cb1-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;distMatches &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;data_frame&lt;/span&gt;(&lt;span class=&quot;at&quot;&gt;method=&lt;/span&gt;methods) &lt;span class=&quot;sc&quot;&gt;%&amp;gt;%&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;group_by&lt;/span&gt;(method) &lt;span class=&quot;sc&quot;&gt;%&amp;gt;%&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;do&lt;/span&gt;({&lt;/span&gt;
&lt;span id=&quot;cb1-3&quot;&gt;&lt;a href=&quot;#cb1-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  guess &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; names2[&lt;span class=&quot;fu&quot;&gt;apply&lt;/span&gt;(&lt;span class=&quot;fu&quot;&gt;stringdistmatrix&lt;/span&gt;(true_matches&lt;span class=&quot;sc&quot;&gt;$&lt;/span&gt;name1, names2, .&lt;span class=&quot;sc&quot;&gt;$&lt;/span&gt;method), &lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;, which.min)]&lt;/span&gt;
&lt;span id=&quot;cb1-4&quot;&gt;&lt;a href=&quot;#cb1-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;fu&quot;&gt;mutate&lt;/span&gt;(true_matches, &lt;span class=&quot;at&quot;&gt;name2.guess=&lt;/span&gt;guess)&lt;/span&gt;
&lt;span id=&quot;cb1-5&quot;&gt;&lt;a href=&quot;#cb1-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;}) &lt;span class=&quot;sc&quot;&gt;%&amp;gt;%&lt;/span&gt; ungroup&lt;/span&gt;
&lt;span id=&quot;cb1-6&quot;&gt;&lt;a href=&quot;#cb1-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-7&quot;&gt;&lt;a href=&quot;#cb1-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;distMatches &lt;span class=&quot;sc&quot;&gt;%&amp;gt;%&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;group_by&lt;/span&gt;(method) &lt;span class=&quot;sc&quot;&gt;%&amp;gt;%&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-8&quot;&gt;&lt;a href=&quot;#cb1-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;fu&quot;&gt;summarise&lt;/span&gt;(&lt;span class=&quot;at&quot;&gt;score=&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;mean&lt;/span&gt;(name2&lt;span class=&quot;sc&quot;&gt;==&lt;/span&gt;name2.guess)) &lt;span class=&quot;sc&quot;&gt;%&amp;gt;%&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-9&quot;&gt;&lt;a href=&quot;#cb1-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;fu&quot;&gt;arrange&lt;/span&gt;(&lt;span class=&quot;fu&quot;&gt;desc&lt;/span&gt;(score))&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;table&gt;
&lt;tr&gt;
&lt;th&gt;
&lt;/th&gt;
&lt;th&gt;
method
&lt;/th&gt;
&lt;th&gt;
score
&lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;right&quot;&gt;
1
&lt;/td&gt;
&lt;td&gt;
jw
&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;
0.50
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;right&quot;&gt;
2
&lt;/td&gt;
&lt;td&gt;
cosine
&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;
0.36
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;right&quot;&gt;
3
&lt;/td&gt;
&lt;td&gt;
jaccard
&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;
0.32
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;right&quot;&gt;
4
&lt;/td&gt;
&lt;td&gt;
soundex
&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;
0.27
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;right&quot;&gt;
5
&lt;/td&gt;
&lt;td&gt;
lcs
&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;
0.23
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;right&quot;&gt;
6
&lt;/td&gt;
&lt;td&gt;
qgram
&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;
0.23
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;right&quot;&gt;
7
&lt;/td&gt;
&lt;td&gt;
dl
&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;
0.14
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;right&quot;&gt;
8
&lt;/td&gt;
&lt;td&gt;
lv
&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;
0.14
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;right&quot;&gt;
9
&lt;/td&gt;
&lt;td&gt;
osa
&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;
0.14
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;right&quot;&gt;
10
&lt;/td&gt;
&lt;td&gt;
hamming
&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;
0.00
&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;p&gt;Here, score is the fraction of countries successfully matched by a
given method. The highest-scoring method, &lt;a
href=&quot;https://en.wikipedia.org/wiki/Jaro%E2%80%93Winkler_distance&quot;&gt;Jaro–Winkler
distance&lt;/a&gt;, got only half of the countries right. Let’s see what
mistakes it made:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb2&quot;&gt;&lt;pre class=&quot;sourceCode r&quot;&gt;&lt;code class=&quot;sourceCode r&quot;&gt;&lt;span id=&quot;cb2-1&quot;&gt;&lt;a href=&quot;#cb2-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;distMatches &lt;span class=&quot;sc&quot;&gt;%&amp;gt;%&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;filter&lt;/span&gt;(method&lt;span class=&quot;sc&quot;&gt;==&lt;/span&gt;&lt;span class=&quot;st&quot;&gt;&amp;quot;jw&amp;quot;&lt;/span&gt;,name2&lt;span class=&quot;sc&quot;&gt;!=&lt;/span&gt;name2.guess)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;table&gt;
&lt;tr&gt;
&lt;th&gt;
Global Terrorism Database
&lt;/th&gt;
&lt;th&gt;
World Bank
&lt;/th&gt;
&lt;th&gt;
jw’s guess
&lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
Iran
&lt;/td&gt;
&lt;td&gt;
Iran, Islamic Rep. 
&lt;/td&gt;
&lt;td&gt;
Ireland
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
Syria
&lt;/td&gt;
&lt;td&gt;
Syrian Arab Republic
&lt;/td&gt;
&lt;td&gt;
Serbia
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
South Korea
&lt;/td&gt;
&lt;td&gt;
Korea, Rep. 
&lt;/td&gt;
&lt;td&gt;
South Africa
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
Republic of the Congo
&lt;/td&gt;
&lt;td&gt;
Congo, Rep. 
&lt;/td&gt;
&lt;td&gt;
Puerto Rico
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
Ivory Coast
&lt;/td&gt;
&lt;td&gt;
Cote d’Ivoire
&lt;/td&gt;
&lt;td&gt;
Honduras
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
Gambia
&lt;/td&gt;
&lt;td&gt;
Gambia, The
&lt;/td&gt;
&lt;td&gt;
Zambia
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
North Korea
&lt;/td&gt;
&lt;td&gt;
Korea, Dem. People’s Rep. 
&lt;/td&gt;
&lt;td&gt;
North America
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
Macau
&lt;/td&gt;
&lt;td&gt;
Macao SAR, China
&lt;/td&gt;
&lt;td&gt;
Malta
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
Kyrgyzstan
&lt;/td&gt;
&lt;td&gt;
Kyrgyz Republic
&lt;/td&gt;
&lt;td&gt;
Kazakhstan
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
Democratic Republic of the Congo
&lt;/td&gt;
&lt;td&gt;
Congo, Dem. Rep. 
&lt;/td&gt;
&lt;td&gt;
Dominican Republic
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
East Timor
&lt;/td&gt;
&lt;td&gt;
Timor-Leste
&lt;/td&gt;
&lt;td&gt;
Ecuador
&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;p&gt;Why do these distance metrics perform so poorly? In order to
transform “East Timor” to “Timor-Leste”, they need to remove 5
characters on the left and append 6 on the right, which makes a total of
11 edits. On the other hand, to transform “East Timor” to “Ecuador”,
they keep the leading “E” and trailing “or” and replace only 7 letters
in between. These metrics ignore the similarities and focus on the
differences.&lt;/p&gt;
&lt;h2 id=&quot;local-alignment&quot;&gt;Local alignment&lt;/h2&gt;
&lt;p&gt;A similar problem arises in bioinformatics. Let’s say we are
interested in the similarities between the human and bee genomes.
Naturally, these genomes are quite different, and if we perform
&lt;em&gt;global alignment&lt;/em&gt; (as in Levenshtein and most other distance
metrics), the relatively few conserved genes will be lost in the
mismatch noise.&lt;/p&gt;
&lt;p&gt;For this reason, bioinformaticians developed algorithms for &lt;em&gt;local
alignment&lt;/em&gt;, a similarity metric that rewards similarity without
punishing for irrelevant differences. In R, a simple local alignment
algorithm is included in Biostring’s &lt;code&gt;pairwiseAlignment&lt;/code&gt;
function.&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb3&quot;&gt;&lt;pre class=&quot;sourceCode r&quot;&gt;&lt;code class=&quot;sourceCode r&quot;&gt;&lt;span id=&quot;cb3-1&quot;&gt;&lt;a href=&quot;#cb3-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;localMatches &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; true_matches &lt;span class=&quot;sc&quot;&gt;%&amp;gt;%&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-2&quot;&gt;&lt;a href=&quot;#cb3-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;fu&quot;&gt;mutate&lt;/span&gt;(name1 &lt;span class=&quot;sc&quot;&gt;%&amp;gt;%&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-3&quot;&gt;&lt;a href=&quot;#cb3-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;fu&quot;&gt;sapply&lt;/span&gt;(&lt;span class=&quot;cf&quot;&gt;function&lt;/span&gt;(n)&lt;/span&gt;
&lt;span id=&quot;cb3-4&quot;&gt;&lt;a href=&quot;#cb3-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;fu&quot;&gt;pairwiseAlignment&lt;/span&gt;(names2, n, &lt;span class=&quot;at&quot;&gt;type=&lt;/span&gt;&lt;span class=&quot;st&quot;&gt;&amp;quot;local&amp;quot;&lt;/span&gt;, &lt;span class=&quot;at&quot;&gt;scoreOnly=&lt;/span&gt;T) &lt;span class=&quot;sc&quot;&gt;%&amp;gt;%&lt;/span&gt; which.max) &lt;span class=&quot;sc&quot;&gt;%&amp;gt;%&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-5&quot;&gt;&lt;a href=&quot;#cb3-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    names2[.])&lt;/span&gt;
&lt;span id=&quot;cb3-6&quot;&gt;&lt;a href=&quot;#cb3-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;localMatches &lt;span class=&quot;sc&quot;&gt;%&amp;gt;%&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;summarize&lt;/span&gt;(&lt;span class=&quot;at&quot;&gt;score=&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;mean&lt;/span&gt;(name2&lt;span class=&quot;sc&quot;&gt;==&lt;/span&gt;name2.guess))&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The local alignment method guessed 77% of the countries, compared to
only 50% countries guessed by the best distance metric. Here are the
countries it didn’t guess:&lt;/p&gt;
&lt;table&gt;
&lt;tr&gt;
&lt;th&gt;
Global Terrorism Database
&lt;/th&gt;
&lt;th&gt;
World Bank
&lt;/th&gt;
&lt;th&gt;
Local alignment’s guess
&lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
South Korea
&lt;/td&gt;
&lt;td&gt;
Korea, Rep. 
&lt;/td&gt;
&lt;td&gt;
South Asia
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
Republic of the Congo
&lt;/td&gt;
&lt;td&gt;
Congo, Rep. 
&lt;/td&gt;
&lt;td&gt;
Central African Republic
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
North Korea
&lt;/td&gt;
&lt;td&gt;
Korea, Dem. People’s Rep. 
&lt;/td&gt;
&lt;td&gt;
Middle East &amp;amp; North Africa
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
Democratic Republic of the Congo
&lt;/td&gt;
&lt;td&gt;
Congo, Dem. Rep. 
&lt;/td&gt;
&lt;td&gt;
Central African Republic
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
East Timor
&lt;/td&gt;
&lt;td&gt;
Timor-Leste
&lt;/td&gt;
&lt;td&gt;
East Asia &amp;amp; Pacific (excluding high income)
&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;p&gt;Every mistake is caused by a lengthy generic qualifier such as South,
North, East, or Republic.&lt;/p&gt;
&lt;p&gt;Why isn’t local alignment included in the stringdist package? Well,
here’s the thing: strictly speaking, it is not a distance. Any distance
metric must obey the &lt;a
href=&quot;https://en.wikipedia.org/wiki/Triangle_inequality#Metric_space&quot;&gt;triangle
inequality&lt;/a&gt;:&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;math display&quot;&gt;\[d(x,z)\leq d(x,y)+d(y,z).\]&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;The local alignment score does not satisfy it: the phrase “local
alignment” is highly (locally) similar to both “local” and “alignment”,
but “local” and “alignment” are not similar at all.&lt;/p&gt;
&lt;p&gt;Does this matter? In some applications, perhaps. But for country
names matching, it sure looks like local alignment beats any of the
“proper” distance metrics.&lt;/p&gt;
&lt;p&gt;And yet local alignment didn’t guess everything it could. I
experimented briefly with a multi-alignment algorithm, but, at least in
this case, it performed only a little bit better.&lt;/p&gt;
</description>
                        <pubDate>Sun, 11 Dec 2016 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2016-12-11-local-alignment</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2016-12-11-local-alignment.html</guid>
                </item>
        
                <item>
                        <title>Accuracy of quantile estimation through sampling</title>
                        <description>&lt;p&gt;In Bayesian data analysis, a typical workflow is:&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;Draw samples &lt;span class=&quot;math inline&quot;&gt;\(\theta\)&lt;/span&gt; from the
posterior distribution &lt;span class=&quot;math inline&quot;&gt;\(p(\theta|y)\)&lt;/span&gt;
using &lt;a
href=&quot;https://en.wikipedia.org/wiki/Markov_chain_Monte_Carlo&quot;&gt;Markov
chain Monte Carlo&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Compute something of interest based on the drawn samples.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;For instance, computing the &lt;span
class=&quot;math inline&quot;&gt;\(0.025\)&lt;/span&gt; and &lt;span
class=&quot;math inline&quot;&gt;\(0.975\)&lt;/span&gt; quantiles from the samples of a
scalar parameter &lt;span class=&quot;math inline&quot;&gt;\(\theta\)&lt;/span&gt; yields a
&lt;span class=&quot;math inline&quot;&gt;\(95\%\)&lt;/span&gt; &lt;a
href=&quot;https://en.wikipedia.org/wiki/Credible_interval&quot;&gt;credible
interval&lt;/a&gt; for &lt;span class=&quot;math inline&quot;&gt;\(\theta\)&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;But how accurate is the quantile estimation? The accuracy depends on
many factors:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;number of samples&lt;/li&gt;
&lt;li&gt;posterior distribution&lt;/li&gt;
&lt;li&gt;the quantile being estimated&lt;/li&gt;
&lt;li&gt;estimation method&lt;/li&gt;
&lt;li&gt;accuracy metric&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In this article, we consider a fixed posterior distribution &lt;span
class=&quot;math inline&quot;&gt;\((\mathcal{N}(0,1))\)&lt;/span&gt; and accuracy metric
(&lt;a
href=&quot;https://en.wikipedia.org/wiki/Root-mean-square_deviation&quot;&gt;root-mean-square
error (RMSE)&lt;/a&gt;), and investigate how accuracy varies with the number
of samples, quantile, and estimation method.&lt;/p&gt;
&lt;h2 id=&quot;accuracy-depending-on-number-of-samples-and-quantile&quot;&gt;Accuracy
depending on number of samples and quantile&lt;/h2&gt;
&lt;p&gt;There are many ways to compute a sample quantile. We’ll return to
them later. For now, we’ll stick with the simplest method: quantile
&lt;span class=&quot;math inline&quot;&gt;\(p\)&lt;/span&gt; is estimated as &lt;span
class=&quot;math inline&quot;&gt;\(k\)&lt;/span&gt;th order statistic (that is, the &lt;span
class=&quot;math inline&quot;&gt;\(k\)&lt;/span&gt;th-smallest sample), where:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span class=&quot;math inline&quot;&gt;\(k\)&lt;/span&gt; is defined as &lt;span
class=&quot;math inline&quot;&gt;\(n\cdot p\)&lt;/span&gt; rounded to the nearest even
number, except when &lt;span class=&quot;math inline&quot;&gt;\(n\cdot p\)&lt;/span&gt; rounds
down to zero, in which case &lt;span
class=&quot;math inline&quot;&gt;\(k=1\)&lt;/span&gt;;&lt;/li&gt;
&lt;li&gt;&lt;span class=&quot;math inline&quot;&gt;\(n\)&lt;/span&gt; is the total number of
samples;&lt;/li&gt;
&lt;li&gt;&lt;span class=&quot;math inline&quot;&gt;\(p\)&lt;/span&gt; is the quantile to be
estimated (such as &lt;span class=&quot;math inline&quot;&gt;\(0.025\)&lt;/span&gt;).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In R, this can be computed as&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb1&quot;&gt;&lt;pre class=&quot;sourceCode r&quot;&gt;&lt;code class=&quot;sourceCode r&quot;&gt;&lt;span id=&quot;cb1-1&quot;&gt;&lt;a href=&quot;#cb1-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;fu&quot;&gt;quantile&lt;/span&gt;(xs, p, &lt;span class=&quot;at&quot;&gt;names=&lt;/span&gt;F, &lt;span class=&quot;at&quot;&gt;type=&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;3&lt;/span&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Let &lt;span class=&quot;math inline&quot;&gt;\(F(x)\)&lt;/span&gt; and &lt;span
class=&quot;math inline&quot;&gt;\(f(x)\)&lt;/span&gt; be the cumulative distribution
function (cdf) and probability density function (pdf) of the posterior
distribution &lt;span class=&quot;math inline&quot;&gt;\(\mathcal{N}(0,1)\)&lt;/span&gt;. Then
the density function of the &lt;span class=&quot;math inline&quot;&gt;\(k\)&lt;/span&gt;th
order statistic is (see &lt;a
href=&quot;http://www.math.ntu.edu.tw/~hchen/teaching/LargeSample/notes/noteorder.pdf&quot;&gt;here&lt;/a&gt;)&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;math display&quot;&gt;\[f_k(x) = n {n-1\choose
k-1}F(x)^{k-1}f(x)(1-F(x))^{n-k}.\]&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;The true &lt;span class=&quot;math inline&quot;&gt;\(p\)&lt;/span&gt;th quantile is given
by &lt;span class=&quot;math inline&quot;&gt;\(q=F^{-1}(p)\)&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;The root-mean-square error of approximating &lt;span
class=&quot;math inline&quot;&gt;\(q\)&lt;/span&gt; with &lt;span class=&quot;math inline&quot;&gt;\(x\sim
f_k\)&lt;/span&gt; is&lt;/p&gt;
&lt;p&gt;&lt;span
class=&quot;math display&quot;&gt;\[\sqrt{\int_{-\infty}^{\infty}(x-q)^2f_k(x)dx}.\]&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;This would be challenging to calculate analytically, but numerically
it’s not hard at all. Here are the above definitions translated to
R:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb2&quot;&gt;&lt;pre class=&quot;sourceCode r&quot;&gt;&lt;code class=&quot;sourceCode r&quot;&gt;&lt;span id=&quot;cb2-1&quot;&gt;&lt;a href=&quot;#cb2-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;quantileLogDensity &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;cf&quot;&gt;function&lt;/span&gt;(p, n) {&lt;/span&gt;
&lt;span id=&quot;cb2-2&quot;&gt;&lt;a href=&quot;#cb2-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  k &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;max&lt;/span&gt;(&lt;span class=&quot;fu&quot;&gt;round&lt;/span&gt;(n&lt;span class=&quot;sc&quot;&gt;*&lt;/span&gt;p),&lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;)&lt;/span&gt;
&lt;span id=&quot;cb2-3&quot;&gt;&lt;a href=&quot;#cb2-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  coef &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;lchoose&lt;/span&gt;(n&lt;span class=&quot;dv&quot;&gt;-1&lt;/span&gt;, k&lt;span class=&quot;dv&quot;&gt;-1&lt;/span&gt;) &lt;span class=&quot;sc&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;log&lt;/span&gt;(n)&lt;/span&gt;
&lt;span id=&quot;cb2-4&quot;&gt;&lt;a href=&quot;#cb2-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;cf&quot;&gt;function&lt;/span&gt;(x) {&lt;/span&gt;
&lt;span id=&quot;cb2-5&quot;&gt;&lt;a href=&quot;#cb2-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    coef &lt;span class=&quot;sc&quot;&gt;+&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-6&quot;&gt;&lt;a href=&quot;#cb2-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;        &lt;span class=&quot;fu&quot;&gt;dnorm&lt;/span&gt;(x, &lt;span class=&quot;at&quot;&gt;log =&lt;/span&gt; T) &lt;span class=&quot;sc&quot;&gt;+&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-7&quot;&gt;&lt;a href=&quot;#cb2-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;        &lt;span class=&quot;fu&quot;&gt;pnorm&lt;/span&gt;(x, &lt;span class=&quot;at&quot;&gt;log.p =&lt;/span&gt; T)&lt;span class=&quot;sc&quot;&gt;*&lt;/span&gt;(k&lt;span class=&quot;dv&quot;&gt;-1&lt;/span&gt;) &lt;span class=&quot;sc&quot;&gt;+&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-8&quot;&gt;&lt;a href=&quot;#cb2-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;        &lt;span class=&quot;fu&quot;&gt;pnorm&lt;/span&gt;(x, &lt;span class=&quot;at&quot;&gt;log.p =&lt;/span&gt; T, &lt;span class=&quot;at&quot;&gt;lower.tail =&lt;/span&gt; F)&lt;span class=&quot;sc&quot;&gt;*&lt;/span&gt;(n&lt;span class=&quot;sc&quot;&gt;-&lt;/span&gt;k)&lt;/span&gt;
&lt;span id=&quot;cb2-9&quot;&gt;&lt;a href=&quot;#cb2-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;}}&lt;/span&gt;
&lt;span id=&quot;cb2-10&quot;&gt;&lt;a href=&quot;#cb2-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-11&quot;&gt;&lt;a href=&quot;#cb2-11&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;quantileDensity &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;cf&quot;&gt;function&lt;/span&gt;(p, n)&lt;span class=&quot;cf&quot;&gt;function&lt;/span&gt;(x)&lt;/span&gt;
&lt;span id=&quot;cb2-12&quot;&gt;&lt;a href=&quot;#cb2-12&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;fu&quot;&gt;exp&lt;/span&gt;(&lt;span class=&quot;fu&quot;&gt;quantileLogDensity&lt;/span&gt;(p,n)(x))&lt;/span&gt;
&lt;span id=&quot;cb2-13&quot;&gt;&lt;a href=&quot;#cb2-13&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-14&quot;&gt;&lt;a href=&quot;#cb2-14&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;rmse &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;cf&quot;&gt;function&lt;/span&gt;(p, n) {&lt;/span&gt;
&lt;span id=&quot;cb2-15&quot;&gt;&lt;a href=&quot;#cb2-15&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  q &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;qnorm&lt;/span&gt;(p)&lt;/span&gt;
&lt;span id=&quot;cb2-16&quot;&gt;&lt;a href=&quot;#cb2-16&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  qd &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;quantileDensity&lt;/span&gt;(p, n)&lt;/span&gt;
&lt;span id=&quot;cb2-17&quot;&gt;&lt;a href=&quot;#cb2-17&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;fu&quot;&gt;sqrt&lt;/span&gt;(&lt;span class=&quot;fu&quot;&gt;integrate&lt;/span&gt;(&lt;span class=&quot;cf&quot;&gt;function&lt;/span&gt;(x){&lt;span class=&quot;fu&quot;&gt;qd&lt;/span&gt;(x) &lt;span class=&quot;sc&quot;&gt;*&lt;/span&gt; (q&lt;span class=&quot;sc&quot;&gt;-&lt;/span&gt;x)&lt;span class=&quot;sc&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;2&lt;/span&gt;}, &lt;span class=&quot;sc&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;cn&quot;&gt;Inf&lt;/span&gt;, &lt;span class=&quot;cn&quot;&gt;Inf&lt;/span&gt;)&lt;span class=&quot;sc&quot;&gt;$&lt;/span&gt;value)&lt;/span&gt;
&lt;span id=&quot;cb2-18&quot;&gt;&lt;a href=&quot;#cb2-18&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Note that everything is computed through logarithms to avoid over-
and underflow.&lt;/p&gt;
&lt;p&gt;And here is the result:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/img/quantile-accuracy/accuracy1.png&quot; /&gt;&lt;/p&gt;
&lt;h2 id=&quot;accuracy-depending-on-method&quot;&gt;Accuracy depending on method&lt;/h2&gt;
&lt;p&gt;The method we used above to estimate the population quantile based on
sample’s ordered statistics is not the only one. There is a &lt;a
href=&quot;https://www.amherst.edu/media/view/129116/original/Sample+Quantiles.pdf&quot;&gt;class
of quantile estimators&lt;/a&gt; based on various weighted sums of order
statistics.&lt;/p&gt;
&lt;p&gt;As these estimators are already &lt;a
href=&quot;https://stat.ethz.ch/R-manual/R-devel/library/stats/html/quantile.html&quot;&gt;implemented
in R’s &lt;code&gt;quantile&lt;/code&gt; function&lt;/a&gt; as different “types”, we’ll
save some time and compare them by simulation instead of computing the
integrals.&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb3&quot;&gt;&lt;pre class=&quot;sourceCode r&quot;&gt;&lt;code class=&quot;sourceCode r&quot;&gt;&lt;span id=&quot;cb3-1&quot;&gt;&lt;a href=&quot;#cb3-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;simulationRmse &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;cf&quot;&gt;function&lt;/span&gt;(p, n, method) {&lt;/span&gt;
&lt;span id=&quot;cb3-2&quot;&gt;&lt;a href=&quot;#cb3-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;fu&quot;&gt;replicate&lt;/span&gt;(&lt;span class=&quot;dv&quot;&gt;10&lt;/span&gt;, {&lt;/span&gt;
&lt;span id=&quot;cb3-3&quot;&gt;&lt;a href=&quot;#cb3-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    qs &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;replicate&lt;/span&gt;(&lt;span class=&quot;dv&quot;&gt;300&lt;/span&gt;, &lt;span class=&quot;fu&quot;&gt;quantile&lt;/span&gt;(&lt;span class=&quot;fu&quot;&gt;rnorm&lt;/span&gt;(n), p, &lt;span class=&quot;at&quot;&gt;type =&lt;/span&gt; method, &lt;span class=&quot;at&quot;&gt;names =&lt;/span&gt; F))&lt;/span&gt;
&lt;span id=&quot;cb3-4&quot;&gt;&lt;a href=&quot;#cb3-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;fu&quot;&gt;sqrt&lt;/span&gt;(&lt;span class=&quot;fu&quot;&gt;mean&lt;/span&gt;((qs&lt;span class=&quot;sc&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;qnorm&lt;/span&gt;(p))&lt;span class=&quot;sc&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;2&lt;/span&gt;))})&lt;/span&gt;
&lt;span id=&quot;cb3-5&quot;&gt;&lt;a href=&quot;#cb3-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Since RMSE is now a random quantity, we estimate it 10 times and
display as a boxplot to visualize the uncertainty.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/img/quantile-accuracy/accuracy2.png&quot; /&gt;&lt;/p&gt;
&lt;h2 id=&quot;conclusions&quot;&gt;Conclusions&lt;/h2&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;The estimates of more extreme quantiles (such as &lt;span
class=&quot;math inline&quot;&gt;\(0.025\)&lt;/span&gt;) are less accurate. See also &lt;a
href=&quot;http://stats.stackexchange.com/q/248113/97654&quot;&gt;Are 50% confidence
intervals more robustly estimated than 95% confidence
intervals?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;The naive quantile estimator (type 3) is not great on smaller sample
sizes; there are many better alternatives. R’s default type 7 fares
well.&lt;/li&gt;
&lt;li&gt;Increasing the number of samples improves accuracy (albeit with
diminishing returns) and can compensate for an extreme quantile.&lt;/li&gt;
&lt;li&gt;For a parameter that is approximately normally distributed with
standard deviation &lt;span class=&quot;math inline&quot;&gt;\(\sigma\)&lt;/span&gt;, to
estimate its &lt;span class=&quot;math inline&quot;&gt;\(0.025\)&lt;/span&gt; quantile within
&lt;span class=&quot;math inline&quot;&gt;\(0.1\sigma\)&lt;/span&gt;, we need about &lt;span
class=&quot;math inline&quot;&gt;\(750\)&lt;/span&gt; samples. For the &lt;span
class=&quot;math inline&quot;&gt;\(0.25\)&lt;/span&gt; quantile we need only &lt;span
class=&quot;math inline&quot;&gt;\(200\)&lt;/span&gt; samples.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;This article was inspired by an exercise from &lt;a
href=&quot;http://www.stat.columbia.edu/~gelman/book/&quot;&gt;Bayesian Data
Analysis&lt;/a&gt; (exercise 1, chapter 10).&lt;/p&gt;
</description>
                        <pubDate>Wed, 30 Nov 2016 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2016-11-30-quantile-accuracy</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2016-11-30-quantile-accuracy.html</guid>
                </item>
        
                <item>
                        <title>RNA-Seq normalization explained</title>
                        <description>&lt;p&gt;RNA-Seq (short for RNA sequencing) is a type of experiment that lets
us measure gene expression. The sequencing step produces a large number
(tens of millions) of cDNA&lt;a href=&quot;#fn1&quot; class=&quot;footnote-ref&quot;
id=&quot;fnref1&quot; role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;1&lt;/sup&gt;&lt;/a&gt; fragment sequences
called reads. Every read represents a part of some RNA molecule in the
sample&lt;a href=&quot;#fn2&quot; class=&quot;footnote-ref&quot; id=&quot;fnref2&quot;
role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;2&lt;/sup&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Then we assign (“map”) every read to one of the isoforms and count
how many reads each isoform has got.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/img/rna-seq-normalization/count1.svg&quot; /&gt;&lt;/p&gt;
&lt;p&gt;All else being equal, the more abundant an isoform is, the more
fragments from it are likely to be sequenced. Therefore, we can use read
counts as a proxy for isoform abundance.&lt;/p&gt;
&lt;p&gt;However, since “all else” is never equal, the counts need to be
adjusted to be comparable across isoforms, samples, and experiments.
Here we will explore these adjustments and why they are necessary.&lt;/p&gt;
&lt;h2 id=&quot;rpk&quot;&gt;RPK&lt;/h2&gt;
&lt;p&gt;Consider the following mapped reads from an RNA-Seq experiment. Which
isoform is more abundant, the red one or the yellow one?&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/img/rna-seq-normalization/count3.svg&quot; /&gt;&lt;/p&gt;
&lt;p&gt;The yellow isoform has got more reads assigned to it, but it is also
much longer than the red one. The longer the isoform, the more fragments
(and, therefore, reads) we should expect it to generate.&lt;/p&gt;
&lt;p&gt;To be able to compare read counts across isoforms, we divide the
counts by the isoform length. It is also customary to multiply the
number by &lt;span class=&quot;math inline&quot;&gt;\(1000\)&lt;/span&gt;, obtaining &lt;em&gt;reads
per kilobase&lt;/em&gt;:&lt;/p&gt;
&lt;p&gt;&lt;span
class=&quot;math display&quot;&gt;\[RPK_i=10^3\cdot\frac{n_i}{l_i},\]&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;where &lt;span class=&quot;math inline&quot;&gt;\(n_i\)&lt;/span&gt; is the number of reads
mapped to isoform &lt;span class=&quot;math inline&quot;&gt;\(i\)&lt;/span&gt;, and &lt;span
class=&quot;math inline&quot;&gt;\(l_i\)&lt;/span&gt; is the length of that isoform.&lt;/p&gt;
&lt;h2 id=&quot;rpkm-and-rpm&quot;&gt;RPKM and RPM&lt;/h2&gt;
&lt;p&gt;Consider the data from two RNA-Seq experiments. In which one is the
red isoform more expressed?&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/img/rna-seq-normalization/count5.svg&quot; /&gt;&lt;/p&gt;
&lt;p&gt;If we rely on raw counts, the first experiment has produced more red
fragments, and so we may conclude that the red isoform is more expressed
there.&lt;/p&gt;
&lt;p&gt;Computing &lt;span class=&quot;math inline&quot;&gt;\(RPK\)&lt;/span&gt; won’t change
anything since we are comparing expression of the same isoform.&lt;/p&gt;
&lt;p&gt;But the first experiment has produced more total fragments sequenced,
and the higher the overall number of reads is, the higher count we
should expect for any given isoform.&lt;/p&gt;
&lt;p&gt;To compare counts across experiments, we should further normalize by
the total fragment count (usually expressed in millions). Thus,
&lt;em&gt;reads per kilobase per million&lt;/em&gt; is computed as&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;math display&quot;&gt;\[RPKM_i=10^9\cdot\frac{n_i}{l_i\cdot
\sum_j n_j}.\]&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;If we do not intend to compare abundances across isoforms, then
simply &lt;em&gt;reads per million&lt;/em&gt; will do:&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;math display&quot;&gt;\[RPM_i=10^6\cdot\frac{n_i}{\sum_j
n_j}.\]&lt;/span&gt;&lt;/p&gt;
&lt;h2 id=&quot;tpm&quot;&gt;TPM&lt;/h2&gt;
&lt;p&gt;Here we consider RNA-Seq data from two different tissues. For
simplicity, let’s make a (completely unrealistic) assumption that in
each tissue, only two isoforms are expressed: red and yellow in tissue
1, and red and green in tissue 2. We are interested in the difference in
expression of the red isoform in the two tissues.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/img/rna-seq-normalization/count7.svg&quot; /&gt;&lt;/p&gt;
&lt;p&gt;The number of reads for the red isoform is the same in both cases.
Since we are comparing the expression of the same isoform, the &lt;span
class=&quot;math inline&quot;&gt;\(RPK\)&lt;/span&gt; values will be identical too.
Furthermore, the total number of reads is the same between the
experiments, so even the &lt;span class=&quot;math inline&quot;&gt;\(RPKM\)&lt;/span&gt;
values won’t show any difference. But is there one?&lt;/p&gt;
&lt;p&gt;Imagine for a second that there is an equal number of red and yellow
transcripts in the tissue 1 sample. Since the red isoform is longer than
the yellow one, it yields more fragments, and so we should observe more
red reads than yellow ones. Yet we see more yellow reads. This means
that the number of red transcripts is significantly lower than the
number of yellow transcripts.&lt;/p&gt;
&lt;p&gt;If we conduct the same thought experiment with tissue 2, we would
expect somewhat more green fragments than red ones, and this is what we
observe. The relative abundance of the red isoform in tissue 2 is
probably close to &lt;span class=&quot;math inline&quot;&gt;\(50\%\)&lt;/span&gt; and thus is
higher than in tissue 1.&lt;/p&gt;
&lt;p&gt;The formula for &lt;span class=&quot;math inline&quot;&gt;\(RPKM_i\)&lt;/span&gt; takes
into account the length of isoform &lt;span
class=&quot;math inline&quot;&gt;\(i\)&lt;/span&gt; only. But the lengths of other isoforms
clearly have an impact on the relative number of isoform &lt;span
class=&quot;math inline&quot;&gt;\(i\)&lt;/span&gt;’s fragments.&lt;/p&gt;
&lt;p&gt;The metric called &lt;span class=&quot;math inline&quot;&gt;\(TPM\)&lt;/span&gt;, or
transcripts per million, directly measures the relative abundance of
transcripts. To estimate it from the count data, notice that the &lt;span
class=&quot;math inline&quot;&gt;\(RPK\)&lt;/span&gt; values are proportional to the
abundances of isoforms within a single experiment. Thus the abundance of
isoform &lt;span class=&quot;math inline&quot;&gt;\(i\)&lt;/span&gt; per million transcripts
can be estimated as&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;math display&quot;&gt;\[TPM_i=10^6\cdot\frac{RPK_i}{\sum_j
RPK_j}=10^6\cdot\frac{n_i/l_i}{\sum_j n_j/l_j}.\]&lt;/span&gt;&lt;/p&gt;
&lt;h2 id=&quot;relative-vs.-absolute-expression&quot;&gt;Relative vs. absolute
expression&lt;/h2&gt;
&lt;p&gt;So far we have been estimating the relative abundance, i.e. what
proportion of transcripts in a sample belong to a particular isoform.
Can we estimate the absolute abundance from RNA-Seq data?&lt;/p&gt;
&lt;p&gt;Consider the two cells drawn below. The colored squiggly lines
represent individual transcripts of the corresponding isoforms.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/img/rna-seq-normalization/count8.svg&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Cell B has twice as many transcripts of each isoform as cell A. If we
conduct RNA-Seq experiments in the two cells, we would get samples from
essentially the same distribution. We wouldn’t be able to tell the cells
apart based on their RNA-Seq.&lt;/p&gt;
&lt;p&gt;Here’s a trick: during library preparation, we add a known amount of
an artificial RNA or DNA that is not produced by the studied organism
(the blue squiggle below), then we can compare all abundances against
it. This artificially introduced material is called a spike-in.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/img/rna-seq-normalization/count9.svg&quot; /&gt;&lt;/p&gt;
&lt;p&gt;If we regard the spike-in as isoform &lt;span
class=&quot;math inline&quot;&gt;\(0\)&lt;/span&gt;, with the known absolute abundance of
&lt;span class=&quot;math inline&quot;&gt;\(T_0\)&lt;/span&gt; transcripts, then the absolute
abundance of isoform &lt;span class=&quot;math inline&quot;&gt;\(i\)&lt;/span&gt; can be
estimated as&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;math display&quot;&gt;\[T_i =
T_0\cdot\frac{RPK_i}{RPK_0}=T_0\cdot\frac{n_i/l_i}{n_0/l_0}.\]&lt;/span&gt;&lt;/p&gt;
&lt;h2 id=&quot;dangers-of-relative-expression&quot;&gt;Dangers of relative
expression&lt;/h2&gt;
&lt;p&gt;Whether we care about absolute or relative expression depends on the
biological question in hand. However, looking at relative expression
alone can produce unexpected results.&lt;/p&gt;
&lt;p&gt;Suppose again that only two isoforms are being expressed, red and
yellow. In condition A, the two isoforms are equally expressed. In
condition B, the yellow isoform’s expression doubles, while the red
isoform’s expression is not affected at all.&lt;/p&gt;
&lt;figure&gt;
&lt;img src=&quot;/img/rna-seq-normalization/absexpr.svg&quot; style=&quot;max-height: 400px;&quot;&gt;
&lt;/figure&gt;
&lt;p&gt;Now let’s look at the relative expression:&lt;/p&gt;
&lt;figure&gt;
&lt;img src=&quot;/img/rna-seq-normalization/relexpr.svg&quot; style=&quot;max-height: 400px;&quot;&gt;
&lt;/figure&gt;
&lt;p&gt;Based on this chart, we might conclude that the red isoform is also
differentially expressed between the two conditions. Technically this is
true, as long as we are talking about relative expression, but this is
only a consequence of the overexpression of the yellow isoform.&lt;/p&gt;
&lt;h2 id=&quot;further-reading-and-watching&quot;&gt;Further reading and watching&lt;/h2&gt;
&lt;p&gt;This article is a transcribed part of a talk I gave in Kiev on
November 27, 2016. You can look through the &lt;a
href=&quot;/docs/2016-11-27-rna-seq.pdf&quot;&gt;slides&lt;/a&gt; (in English) and watch
the &lt;a href=&quot;https://www.youtube.com/watch?v=yShm19D-36Q&quot;&gt;video&lt;/a&gt; (in
Russian).&lt;/p&gt;
&lt;p&gt;Other resources:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=5NiFibnbE8o&quot;&gt;CSHL Keynote
by Lior Pachter&lt;/a&gt;, where he talks about the different expression
measures in the last part of the talk&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://arxiv.org/pdf/1609.00959v1.pdf&quot;&gt;Selecting
Between-Sample RNA-Seq Normalization Methods from the Perspective of
their Assumptions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a
href=&quot;https://haroldpimentel.wordpress.com/2014/12/08/in-rna-seq-2-2-between-sample-normalization/&quot;&gt;In
RNA-Seq, 2 != 2: Between-sample normalization&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;section id=&quot;footnotes&quot; class=&quot;footnotes footnotes-end-of-document&quot;
role=&quot;doc-endnotes&quot;&gt;
&lt;hr /&gt;
&lt;ol&gt;
&lt;li id=&quot;fn1&quot;&gt;&lt;p&gt;complementary DNA, meaning the DNA that has been
reverse-transcribed from RNA&lt;a href=&quot;#fnref1&quot; class=&quot;footnote-back&quot;
role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li id=&quot;fn2&quot;&gt;&lt;p&gt;for simplicity, I do not consider paired-end sequencing
here&lt;a href=&quot;#fnref2&quot; class=&quot;footnote-back&quot;
role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</description>
                        <pubDate>Mon, 28 Nov 2016 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2016-11-28-rna-seq-normalization</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2016-11-28-rna-seq-normalization.html</guid>
                </item>
        
                <item>
                        <title>Make ~/.pam_environment work again</title>
                        <description>&lt;p&gt;In the early days of Linux, when we used to start X with
&lt;code&gt;startx&lt;/code&gt;, your GUI environment was directly inherited from
your console environment. So if you wanted to set or change an
environment variable, you’d just put it in &lt;code&gt;~/.profile&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Nowadays we use display managers such as &lt;code&gt;gdm&lt;/code&gt;, and the
recommended way to set environment variables is in
&lt;code&gt;~/.pam_environment&lt;/code&gt;, which is read by the
&lt;code&gt;pam_env&lt;/code&gt; module. The syntax of that file is&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;PATH OVERRIDE=/usr/local/bin:/bin:/usr/bin:/sbin:/usr/sbin
LANG OVERRIDE=en_US.UTF-8&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;After a recent update I noticed that even this stopped working. Turns
out that this feature was marked as a &lt;a
href=&quot;https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2010-4708&quot;&gt;security
issue&lt;/a&gt; and disabled by default.&lt;/p&gt;
&lt;p&gt;On a typical laptop or personal computer, where there are no hostile
local users, you can enable it back.&lt;/p&gt;
&lt;h2
id=&quot;check-whether-your-pam-configuration-is-managed-by-authselect&quot;&gt;Check
whether your PAM configuration is managed by authselect&lt;/h2&gt;
&lt;p&gt;On newer systems (at least the RedHat-derived ones; not sure about
the others) &lt;strong&gt;authselect&lt;/strong&gt; is used to manage the
configuration files in &lt;code&gt;/etc/pam.d&lt;/code&gt;. To check if your system
uses authselect, run&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;authselect check&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;On a system that uses authselect, you will get something like&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Current configuration is valid.&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;On a system that doesn’t use authselect, you’ll get either an error
message indicating that there’s no &lt;code&gt;authselect&lt;/code&gt; installed
(e.g. &lt;code&gt;authselect: No such file or directory&lt;/code&gt;) or some kind
of message from &lt;code&gt;authselect&lt;/code&gt; telling you that it’s not being
used.&lt;/p&gt;
&lt;h2 id=&quot;if-authselect-is-used&quot;&gt;If authselect is used&lt;/h2&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;&lt;p&gt;Create a custom authselect profile:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;authselect create-profile minimal_with_env -b minimal --symlink-meta --symlink-pam&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Edit the file
&lt;code&gt;/etc/authselect/custom/minimal_with_env/password-auth&lt;/code&gt;. Find
the line that says&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;auth       required    pam_env.so&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;and change it to&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;auth       required    pam_env.so user_readenv=1&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Switch to the new profile:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;authselect select custom/minimal_with_env&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;if-authselect-is-not-used&quot;&gt;If authselect is not used&lt;/h2&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;&lt;p&gt;Find the file in &lt;code&gt;/etc/pam.d&lt;/code&gt; that corresponds to your
display manager, such as &lt;code&gt;/etc/pam.d/lightdm&lt;/code&gt; for lightdm. If
you are logging in via the tty directly, skipping a display manager, see
&lt;code&gt;/etc/pam.d/login&lt;/code&gt;, but note that e.g. on Fedora 31 the
setting is delegated to &lt;code&gt;/etc/pam.d/system-auth&lt;/code&gt;, which is
then sourced.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Find the line in that file that says&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;auth       required    pam_env.so&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;and change it to&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;auth       required    pam_env.so user_readenv=1&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Restart your display manager.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;You may also need to disable SELinux; otherwise you may be seeing
errors like these in journalctl:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Dec 05 10:47:31 jerry audit[69035]: AVC avc:  denied  { read } for  pid=69035 comm=&amp;quot;login&amp;quot; name=&amp;quot;.pam_environment&amp;quot; dev=&amp;quot;dm-2&amp;quot; ino=12063987 scontext=system_u:system_r:local_login_t:s0-s0:c0.c1023 tcontext=unconfined_u:object_r:user_home_t:s0 tclass=file permissive=1
Dec 05 10:47:31 jerry audit[69035]: AVC avc:  denied  { open } for  pid=69035 comm=&amp;quot;login&amp;quot; path=&amp;quot;/home/roman/.pam_environment&amp;quot; dev=&amp;quot;dm-2&amp;quot; ino=12063987 scontext=system_u:system_r:local_login_t:s0-s0:c0.c1023 tcontext=unconfined_u:object_r:user_home_t:s0 tclass=file permissive=1&lt;/code&gt;&lt;/pre&gt;
</description>
                        <pubDate>Tue, 08 Nov 2016 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2016-11-08-pam_environment</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2016-11-08-pam_environment.html</guid>
                </item>
        
                <item>
                        <title>Electoral vote distributions are polynomials</title>
                        <description>&lt;p&gt;In his article &lt;a
href=&quot;http://www.haskellforall.com/2016/10/electoral-vote-distributions-are-monoids.html&quot;&gt;Electoral
vote distributions are Monoids&lt;/a&gt;, Gabriel Gonzalez poses and answers
the following question based on &lt;a
href=&quot;http://projects.fivethirtyeight.com/2016-election-forecast/&quot;&gt;538’s
data&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;what would be Hillary’s chance of winning if each state’s probability
of winning was truly independent of one another?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;To answer the question, Gabriel devises a divide-and-conquer
algorithm. He computes probability distributions over vote counts in
subsets of all states and then combines them. He also observes that vote
distributions form a monoid.&lt;/p&gt;
&lt;p&gt;Here I want to share an algebraic perspective on vote counting and
show &lt;em&gt;why&lt;/em&gt; distributions form a monoid.&lt;/p&gt;
&lt;p&gt;Let &lt;span class=&quot;math inline&quot;&gt;\(p_i\)&lt;/span&gt; be the probability of
Hillary’s victory in state &lt;span class=&quot;math inline&quot;&gt;\(i\)&lt;/span&gt;, and
&lt;span class=&quot;math inline&quot;&gt;\(n_i\)&lt;/span&gt; be the number of electoral
college votes for that state, where &lt;span
class=&quot;math inline&quot;&gt;\(i=1,\ldots,N\)&lt;/span&gt;, and &lt;span
class=&quot;math inline&quot;&gt;\(N\)&lt;/span&gt; is the total number of states (and
districts; see Gabriel’s post for details).&lt;/p&gt;
&lt;p&gt;Then a vote distribution is a collection of probabilities &lt;span
class=&quot;math inline&quot;&gt;\(q_k\)&lt;/span&gt; that Hillary will get exactly &lt;span
class=&quot;math inline&quot;&gt;\(k\)&lt;/span&gt; votes:&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;math display&quot;&gt;\[
\newcommand{\p}[1]{\mathrm{Pr}\{#1\}}
\begin{equation}
q_k = \p{\text{number of votes for H.Clinton} =
k},\;k=1,\ldots,\sum_{i=1}^N
n_i.
\end{equation}
\]&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Consider the following polynomial:&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;math display&quot;&gt;\[Q(x)=\prod_{i=1}^N\left(p_i
x^{n_i}+(1-p_i)\right).\]&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;This is a product of &lt;span class=&quot;math inline&quot;&gt;\(N\)&lt;/span&gt; brackets,
one for each state. If we expanded it, we would get &lt;span
class=&quot;math inline&quot;&gt;\(2^N\)&lt;/span&gt; terms. Every such term takes either
&lt;span class=&quot;math inline&quot;&gt;\(p_i x^{n_i}\)&lt;/span&gt; or &lt;span
class=&quot;math inline&quot;&gt;\(1-p_i\)&lt;/span&gt; from each bracket and multiplies
them. Every such term corresponds to a particular election outcome: if
Hillary won in a particular state, take &lt;span class=&quot;math inline&quot;&gt;\(p_i
x^{n_i}\)&lt;/span&gt; from the corresponding bracket; otherwise, take &lt;span
class=&quot;math inline&quot;&gt;\(1-p_i\)&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;For example, if an election outcome means that Hillary won in states
&lt;span class=&quot;math inline&quot;&gt;\(1,4,\ldots\)&lt;/span&gt; and lost in states &lt;span
class=&quot;math inline&quot;&gt;\(2,3,\ldots\)&lt;/span&gt;, then the corresponding term
is&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;math display&quot;&gt;\[
p_1 x^{n_1}(1-p_2)(1-p_3)p_4 x^{n_4}\ldots=p_1(1-p_2)(1-p_3)p_4\ldots
x^{n_1+n_4+\ldots}.
\]&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Notice that &lt;span
class=&quot;math inline&quot;&gt;\(p_1(1-p_2)(1-p_3)p_4\ldots\)&lt;/span&gt; is exactly the
probability of the outcome (under the independence assumption) and &lt;span
class=&quot;math inline&quot;&gt;\(n_1+n_4+\ldots\)&lt;/span&gt; is the number of votes for
Hillary under that outcome.&lt;/p&gt;
&lt;p&gt;Since the power of &lt;span class=&quot;math inline&quot;&gt;\(x\)&lt;/span&gt; in each
term is the number of votes for Hillary, outcomes that result in the
same number of votes, say &lt;span class=&quot;math inline&quot;&gt;\(k\)&lt;/span&gt;,
correspond to like terms. If we combine them, their probabilities
(terms’ coefficients) will add up. To what? To &lt;span
class=&quot;math inline&quot;&gt;\(q_k\)&lt;/span&gt;, the total probability of Hillary
getting &lt;span class=&quot;math inline&quot;&gt;\(k\)&lt;/span&gt; votes.&lt;/p&gt;
&lt;p&gt;Therefore,&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;math display&quot;&gt;\[Q(x) = \sum_{k}q_kx^k.\]&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Deriving the final vote distribution &lt;span
class=&quot;math inline&quot;&gt;\(q_k\)&lt;/span&gt; from &lt;span
class=&quot;math inline&quot;&gt;\(p_i\)&lt;/span&gt; and &lt;span
class=&quot;math inline&quot;&gt;\(n_i\)&lt;/span&gt; is just expanding and reducing &lt;span
class=&quot;math inline&quot;&gt;\(Q(x)\)&lt;/span&gt; from &lt;span
class=&quot;math inline&quot;&gt;\(\prod_{i=1}^N\left(p_i
x^{n_i}+(1-p_i)\right)\)&lt;/span&gt; to &lt;span
class=&quot;math inline&quot;&gt;\(\sum_{k}q_kx^k\)&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;As Gabriel notes, doing this in the direct way would be inefficient.
His divide-and-conquer approach directly translates to expanding &lt;span
class=&quot;math inline&quot;&gt;\(Q(x)\)&lt;/span&gt;: divide all brackets into two
groups, recursively expand the groups, combine the results.&lt;/p&gt;
&lt;p&gt;Under this formulation, it becomes obvious that vote distributions
form a proper monoid: it is just a monoid of polynomials under
multiplication.&lt;/p&gt;
</description>
                        <pubDate>Fri, 28 Oct 2016 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2016-10-28-vote-distributions-polynomials</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2016-10-28-vote-distributions-polynomials.html</guid>
                </item>
        
                <item>
                        <title>Mean-variance ceiling</title>
                        <description>&lt;p&gt;Today I was playing with the &lt;a
href=&quot;https://github.com/cran/NBPSeq/blob/master/man/arab.Rd&quot;&gt;count
data&lt;/a&gt; from a &lt;a
href=&quot;https://www.ncbi.nlm.nih.gov/pubmed/21998647&quot;&gt;small RNA-Seq
experiment performed in &lt;em&gt;Arabidopsis thaliana&lt;/em&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;At some point, I decided to look at the mean-variance relationship
for the fragment counts. As I said, the dataset is small; there are only
3 replicates per condition from which to estimate the variance.
Moreover, each sample is from a different batch. I wasn’t expecting to
see much.&lt;/p&gt;
&lt;p&gt;But there was a pattern in the mean-variance plot that was impossible
to miss.&lt;/p&gt;
&lt;figure&gt;
&lt;img src=&quot;/img/mean-variance-ceiling.png&quot;
alt=&quot;Mean-variance plot of counts per million, log-log scale&quot; /&gt;
&lt;figcaption aria-hidden=&quot;true&quot;&gt;Mean-variance plot of counts per million,
log-log scale&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;It is a nice straight line that many points lie on, but none dare to
cross. A ceiling.&lt;/p&gt;
&lt;p&gt;The ceiling looked mysterious at first, but then I found a simple
explanation. The sample variance of &lt;span
class=&quot;math inline&quot;&gt;\(n\)&lt;/span&gt; numbers &lt;span
class=&quot;math inline&quot;&gt;\(a_1,\ldots,a_n\)&lt;/span&gt; can be written as&lt;/p&gt;
&lt;p&gt;&lt;span
class=&quot;math display&quot;&gt;\[\sigma^2=\frac{n}{n-1}\left(\frac1n\sum_{i=1}^n
a_i^2-\mu^2\right),\]&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;where &lt;span class=&quot;math inline&quot;&gt;\(\mu\)&lt;/span&gt; is the sample mean.
Thus,&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;math display&quot;&gt;\[\frac{\sigma^2}{\mu^2}=\frac{\sum
a_i^2}{(n-1)\mu^2}-\frac{n}{n-1}.\]&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;For non-negative numbers, &lt;span class=&quot;math inline&quot;&gt;\(n^2\mu^2=(\sum
a_i)^2\geq \sum a_i^2\)&lt;/span&gt;, and&lt;/p&gt;
&lt;p&gt;&lt;span
class=&quot;math display&quot;&gt;\[\frac{\sigma^2}{\mu^2}\leq\frac{n^2}{n-1}-\frac{n}{n-1}=n.\]&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;This means that on a log-log plot, all points &lt;span
class=&quot;math inline&quot;&gt;\((\mu,\sigma^2)\)&lt;/span&gt; lie on or below the line
&lt;span class=&quot;math inline&quot;&gt;\(y=2x+\log n\)&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;Moreover, the points that lie exactly on the line correspond to the
samples where all &lt;span class=&quot;math inline&quot;&gt;\(a_i\)&lt;/span&gt; but one are
zero. In other words, those are gene-condition combinations where the
gene’s transcripts were registered in a single replicate for that
condition.&lt;/p&gt;
</description>
                        <pubDate>Thu, 20 Oct 2016 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2016-10-20-mean-variance-ceiling</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2016-10-20-mean-variance-ceiling.html</guid>
                </item>
        
                <item>
                        <title>The rule of 17 in volleyball</title>
                        <description>&lt;p&gt;Scott Adams, the author of &lt;a href=&quot;http://dilbert.com/&quot;&gt;Dilbert&lt;/a&gt;,
writes in his book &lt;a
href=&quot;https://www.goodreads.com/book/show/17859574-how-to-fail-at-almost-everything-and-still-win-big&quot;&gt;“How
to Fail at Almost Everything and Still Win Big”&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Recently I noticed that the high-school volleyball games I attended
in my role as stepdad were almost always won by the team that reached
seventeen first, even though the winning score is twenty-five and you
have to win by two.&lt;/p&gt;
&lt;p&gt;It’s common for the lead to change often during a volleyball match,
and the team that first reaches seventeen might fall behind a few more
times before winning, which makes the pattern extra strange.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Good observation, Scott! But why could it be so?&lt;/p&gt;
&lt;p&gt;Scott offers two possible explanations. One is psychological: the
leading team has a higher morale while the losing team feels defeated.
The other is that perhaps the coach of the losing team sees this as an
opportunity to let his bench players on the court.&lt;/p&gt;
&lt;p&gt;While these reasons sound plausible to me, there is a simpler logical
explanation. It would hold even if the players and coaches were
robots.&lt;/p&gt;
&lt;p&gt;Imagine that you enter a gym where a game is being played. You see
the current score: 15:17. If you know nothing else about the teams
except their current score, which one do you think is more likely to win
the set?&lt;/p&gt;
&lt;p&gt;There are two reasons to think it is the leading team:&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;The score by itself doesn’t offer much evidence that the leading
team is stronger or in a better shape. However, &lt;em&gt;if&lt;/em&gt; one of the
teams is stronger, it is more likely to be the leading team.&lt;/li&gt;
&lt;li&gt;Even without assuming anything about how good the teams are, the
leading team at this moment is up for an easier task: it needs only 8
points to win, whereas the team behind needs 10 points.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;To quantify the reliability of Scott Adams’s “rule of 17”, I wrote a
simple simulation in R:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sim.one &amp;lt;- function(prob, threshold) {
  score &amp;lt;- c(0,0)
  leader &amp;lt;- NA
  serving &amp;lt;- 1
  while (all(score &amp;lt; 25) || abs(diff(score)) &amp;lt; 2) {
    winner &amp;lt;-
      if (as.logical(rbinom(1,1,prob[[serving]])))
        serving
      else
        3 - serving
    score[[winner]] &amp;lt;- score[[winner]] + 1
    serving &amp;lt;- winner
    if (is.na(leader) &amp;amp;&amp;amp; any(score == threshold)) {
      leader &amp;lt;- which.max(score)
    }
  }
  return(c(leader, which.max(score)))
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here &lt;code&gt;prob&lt;/code&gt; is a 2-dimensional vector &lt;span
class=&quot;math inline&quot;&gt;\((p_1,p_2)\)&lt;/span&gt;, where &lt;span
class=&quot;math inline&quot;&gt;\(p_i\)&lt;/span&gt; is the probability of team &lt;span
class=&quot;math inline&quot;&gt;\(i\)&lt;/span&gt; to win their serve against the opposing
team. The function simulates a single set and returns two numbers: which
team first scored &lt;code&gt;threshold&lt;/code&gt; (e.g. 17) points and which team
eventually won. If the two numbers are equal, the rule worked in this
game.&lt;/p&gt;
&lt;p&gt;Then I simulated a game 1000 times for each of many combinations of
&lt;span class=&quot;math inline&quot;&gt;\(p_1\)&lt;/span&gt; and &lt;span
class=&quot;math inline&quot;&gt;\(p_2\)&lt;/span&gt; and calculated the fraction of the
games where the rule worked. Here’s the result:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/img/volleyball-heatmap.png&quot; /&gt;&lt;/p&gt;
&lt;p&gt;When &lt;span class=&quot;math inline&quot;&gt;\(p_1=p_2\)&lt;/span&gt;, the reliability of
the rule is independent of the values of &lt;span
class=&quot;math inline&quot;&gt;\(p_1\)&lt;/span&gt; and &lt;span
class=&quot;math inline&quot;&gt;\(p_2\)&lt;/span&gt; (within the tested limits of &lt;span
class=&quot;math inline&quot;&gt;\(0.3\)&lt;/span&gt; and &lt;span
class=&quot;math inline&quot;&gt;\(0.7\)&lt;/span&gt;) and equals approximately &lt;span
class=&quot;math inline&quot;&gt;\(81\%\)&lt;/span&gt;. This is entirely due to reason 2:
all else being equal, the leading team has a head start.&lt;/p&gt;
&lt;p&gt;When teams are unequal, reason 1 kicks in, and for large
inequalities, the reliability of the rule approaches &lt;span
class=&quot;math inline&quot;&gt;\(1\)&lt;/span&gt;. For instance, when &lt;span
class=&quot;math inline&quot;&gt;\(p_1=0.3\)&lt;/span&gt; and &lt;span
class=&quot;math inline&quot;&gt;\(p_2=0.7\)&lt;/span&gt;, the rule works about &lt;span
class=&quot;math inline&quot;&gt;\(99\%\)&lt;/span&gt; of the time.&lt;/p&gt;
&lt;p&gt;Is there anything magical about the number 17? No, we would expect
the rule to work for any threshold at least to some extent. The
reliability would grow from somewhere around &lt;span
class=&quot;math inline&quot;&gt;\(50\%\)&lt;/span&gt; for the threshold of &lt;span
class=&quot;math inline&quot;&gt;\(1\)&lt;/span&gt; to almost &lt;span
class=&quot;math inline&quot;&gt;\(100\%\)&lt;/span&gt; for the threshold of &lt;span
class=&quot;math inline&quot;&gt;\(25\)&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;And indeed, this is what we observe (for &lt;span
class=&quot;math inline&quot;&gt;\(p_1=p_2\)&lt;/span&gt;):&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/img/volleyball-threshold.png&quot; /&gt;&lt;/p&gt;
&lt;p&gt;This reminds me of &lt;a
href=&quot;https://www.youtube.com/watch?v=HUFj2r755NE&quot;&gt;men’s gold medal
match at the 2012 London Olympics&lt;/a&gt;, where Russia played against
Brazil. Russia loses the first two sets. A game lasts until one of the
teams wins 3 sets in total, so Russia cannot afford to lose a single set
now. In the third set, Brazil continues to lead, reaching 17 (and then
18) points while Russia has 15. Several minutes later, Brazil leads
22:19.&lt;/p&gt;
&lt;p&gt;And then, against all odds, the Russian team wins that set 29:27,
then the two following sets, and gets the gold.&lt;/p&gt;
&lt;figure&gt;
&lt;img src=&quot;/img/volleyball-london2012.jpeg&quot;
alt=&quot;Dmitriy Muserskiy is about to score the gold medal point&quot; /&gt;
&lt;figcaption aria-hidden=&quot;true&quot;&gt;Dmitriy Muserskiy is about to score the
gold medal point&lt;/figcaption&gt;
&lt;/figure&gt;
</description>
                        <pubDate>Wed, 19 Oct 2016 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2016-10-19-volleyball-rule-of-17</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2016-10-19-volleyball-rule-of-17.html</guid>
                </item>
        
                <item>
                        <title>How to prepare a good pull request</title>
                        <description>&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;&lt;p&gt;A pull request should have a specific goal and have a descriptive
title. Do not put multiple unrelated changes in a single pull
request.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Do not include any changes that are irrelevant to the goal of the
pull request.&lt;/p&gt;
&lt;p&gt;This includes refactoring or reformatting unrelated code and changing
or adding auxiliary files (&lt;code&gt;.gitignore&lt;/code&gt;,
&lt;code&gt;.travis.yml&lt;/code&gt; etc.) in a way that is not related to your main
changes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Make logical, not historical commits.&lt;/p&gt;
&lt;p&gt;Before you submit your work for review, you should rebase your branch
(&lt;code&gt;git rebase -i&lt;/code&gt;) and regroup your changes into logical
commits.&lt;/p&gt;
&lt;p&gt;Logical commits achieve different parts of the pull request goal.
Each commit should have a descriptive commit message. Logical commits
within a single pull request rarely overlap in the lines of code they
touch.&lt;/p&gt;
&lt;p&gt;If you want to amend your pull request, rewrite the branch and
force-push it instead of adding new (historical) commits or creating a
new pull request.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Make clean commits. Run
&lt;code&gt;git diff --check origin/master&lt;/code&gt;, and if it reports any
issues like trailing whitespace or missing newlines at the end of the
file, fix them.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;gitignore&quot;&gt;.gitignore&lt;/h2&gt;
&lt;p&gt;My &lt;code&gt;.gitignore&lt;/code&gt; policy is that the project-specific
&lt;code&gt;.gitignore&lt;/code&gt; file should only contain patterns specific for
this project. For instance, if a test suite generates files
&lt;code&gt;*.out&lt;/code&gt;, this pattern belongs to the project’s
&lt;code&gt;.gitignore&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;If a pattern is standard across a wide range of projects
(e.g. &lt;code&gt;*.o&lt;/code&gt;, or &lt;code&gt;.stack-work&lt;/code&gt; for Haskell
projects), then it belongs to the user-specific
&lt;code&gt;~/.gitignore&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&quot;stack.yaml&quot;&gt;stack.yaml&lt;/h2&gt;
&lt;p&gt;(This section is specific to Haskell.)&lt;/p&gt;
&lt;p&gt;My policy is to track &lt;code&gt;stack.yaml&lt;/code&gt; inside the repo for
applications, but not for libraries.&lt;/p&gt;
&lt;p&gt;The rationale is that for an application, &lt;code&gt;stack.yaml&lt;/code&gt;
provides a useful bit of metainformation: which snapshot the app is
guaranteed to build with. Additionally, non-programmers (or non-Haskell
programmers) may want to install the application, and the presence of
&lt;code&gt;stack.yaml&lt;/code&gt; makes it easy for them.&lt;/p&gt;
&lt;p&gt;These benefits do not apply to libraries. And the cost of including
&lt;code&gt;stack.yaml&lt;/code&gt; is:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The snapshot version gets out of date quickly, so you need to update
this file regularly.&lt;/li&gt;
&lt;li&gt;This file is often changed temporarily (e.g. to test a specific
version of a dependency), and if it is tracked, you need to pay
attention not to commit those changes by accident.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;em&gt;UPDATE (2017-06-01):&lt;/em&gt; I now include &lt;code&gt;stack.yaml&lt;/code&gt;
in some of my library repos. The reason is that it is needed for &lt;a
href=&quot;https://github.com/commercialhaskell/stack/blob/master/doc/travis_ci.md&quot;&gt;stack’s
recommended travis configuration&lt;/a&gt;.&lt;/p&gt;
</description>
                        <pubDate>Sun, 18 Sep 2016 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2016-09-18-good-pull-requests</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2016-09-18-good-pull-requests.html</guid>
                </item>
        
                <item>
                        <title>A case for static linking in scientific computing</title>
                        <description>&lt;p&gt;When researchers run scientific software on high-performance
clusters, they often experience problems with shared libraries, such as
this one:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;bcftools: /lib64/libz.so.1: version `ZLIB_1.2.5.2&amp;#39; not found&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Or this one:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;eagle: error while loading shared libraries: libhts.so.1: cannot open shared object file: No such file or directory&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Popular advice points them in the direction of
&lt;code&gt;LD_LIBRARY_PATH&lt;/code&gt;, but a simple and robust solution—static
linking—is often overlooked.&lt;/p&gt;
&lt;p&gt;In this article, I explain the background behind static and dynamic
linking, demonstrate the advantages of static linking, address some of
the objections against static linking, and give instructions on how to
prepare static binaries.&lt;/p&gt;
&lt;h2 id=&quot;what-is-static-and-dynamic-linking&quot;&gt;What is static and dynamic
linking?&lt;/h2&gt;
&lt;p&gt;The word &lt;em&gt;linking&lt;/em&gt; itself refers to the process of assembling
a complete program from libraries of subprograms&lt;a href=&quot;#fn1&quot;
class=&quot;footnote-ref&quot; id=&quot;fnref1&quot;
role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;1&lt;/sup&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Static linking&lt;/em&gt; occurs as the last stage of the compilation
process; the required libraries are embedded in the final binary file of
your program.&lt;/p&gt;
&lt;p&gt;Some (or even all) of the libraries may not be included in the binary
at this stage. In this case, when we attempt to &lt;em&gt;run&lt;/em&gt; the
program, we need &lt;em&gt;dynamic linking&lt;/em&gt; in order to find the libraries
and make the missing subroutines accessible to the program. This second
type of libraries is called &lt;em&gt;dynamic&lt;/em&gt;, or &lt;em&gt;shared&lt;/em&gt;,
libraries. The files with these libraries are usually named
&lt;code&gt;libsomething.so&lt;/code&gt; on Linux and &lt;code&gt;something.dll&lt;/code&gt; on
Windows.&lt;/p&gt;
&lt;p&gt;The rules that an operating system follows when it searches for
dynamic libraries are complex. And simply having &lt;em&gt;a&lt;/em&gt; library in
the right place is not enough; it needs to be the same version of the
library that was used during the compilation, or at least a different
version with the same &lt;a
href=&quot;https://en.wikipedia.org/wiki/Application_binary_interface&quot;&gt;ABI&lt;/a&gt;.
(So no, you shouldn’t
&lt;code&gt;ln -s /usr/lib/libsomething.so.2 /usr/lib/libsomething.so.1&lt;/code&gt;
when a program doesn’t work, contrary to another popular piece of advice
one can find on the Internet.)&lt;/p&gt;
&lt;p&gt;Linux distributions, most of which dynamically link the software they
distribute, manage this by engaging qualified package maintainers and by
having tools and centralized infrastructure to build and distribute
packages.&lt;/p&gt;
&lt;p&gt;But the world of scientific software is not there yet. And if you
fail to take care of your dynamic libraries, the result can vary from a
program refusing to start (as we saw earlier), to a program crash in the
middle of operation, to a hard to detect and diagnose case of data
corruption.&lt;/p&gt;
&lt;p&gt;This is why I think that scientific software should be linked
statically by default.&lt;/p&gt;
&lt;h2 id=&quot;advantages-of-static-linking&quot;&gt;Advantages of static linking&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Reproducibility&lt;/strong&gt;. When a program is linked
statically, it executes the same algorithm wherever it is run. A dynamic
executable executes the code from the version of the dynamic library
that happens to be installed on a particular computing node.&lt;/p&gt;
&lt;p&gt;Note that the static executable doesn’t contain the metainformation
about the library versions used to build it. You should record that
information when you compile the software, and ideally use a &lt;a
href=&quot;https://en.wikipedia.org/wiki/Binary_repository_manager&quot;&gt;binary
repository manager&lt;/a&gt; for your builds.&lt;/p&gt;
&lt;p&gt;But replacing dynamic linking with static linking by itself
dramatically increases the probability that your program will run
tomorrow in the same way as it runs today.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Ease of distribution&lt;/strong&gt;. Suppose that you want your
colleague to run the program you have compiled. If you link statically,
you only need to distribute a single binary. If you link dynamically,
you need to distribute the binary, all dynamic libraries that it depends
on, and the instructions on how to make the binary find its
libraries.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Portability&lt;/strong&gt;. Static linking ensures that you can
compile the program on your Ubuntu laptop and run it on a Debian or
CentOS cluster. With dynamic linking, you’d have to compile it directly
on a cluster or in an identical environment.&lt;/p&gt;
&lt;p&gt;That said, you still need to ensure that both systems use the same or
compatible architectures (the majority of scientific computing happens
on x86-64 anyway), the same OS (probably Linux) and not &lt;em&gt;too&lt;/em&gt;
different kernel versions (or libc versions if you link libc
dynamically).&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;No problems with finding libraries&lt;/strong&gt;. Since no dynamic
libraries are needed, the OS cannot fail to find them. No more
&lt;code&gt;cannot open shared object file&lt;/code&gt; messages. No more
&lt;code&gt;LD_LIBRARY_PATH&lt;/code&gt; tricks.&lt;/p&gt;
&lt;h2 id=&quot;isnt-static-linking-considered-harmful&quot;&gt;Isn’t static linking
considered harmful?&lt;/h2&gt;
&lt;p&gt;Ulrich Drepper &lt;a
href=&quot;https://www.akkadia.org/drepper/no_static_linking.html&quot;&gt;says it
is&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;There are still too many people out there who think (or even insist)
that static linking has benefits. This has never been the case and never
will be the case.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Ulrich certainly knows about this stuff much more than I ever hope
to. But as you can tell from the above quote, he is sometimes a bit
extreme in his judgment.&lt;/p&gt;
&lt;p&gt;There is no shortage of knowledgeable people who &lt;a
href=&quot;http://harmful.cat-v.org/software/dynamic-linking/&quot;&gt;disagree with
him on this issue&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;But more importantly, he looks at linking from a very different
perspective. For many years, he was employed by Red Hat. He was one of
those people who knew a lot about dealing with dynamic libraries and
maintained a centralized repository of packages that worked well
together in a controlled environment.&lt;/p&gt;
&lt;p&gt;It is understandable that he would not care about any of the
advantages I list above (though this is different from claiming that
there has never been and never will be any benefits to static
linking).&lt;/p&gt;
&lt;p&gt;But what about the advantages of the dynamic linking that Ulrich
describes in his article?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Centralized bug/security fixes&lt;/strong&gt;.&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;&lt;p&gt;Security issues matter less for scientific software because it is
not exposed to the outside world.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;HPC cluster users don’t benefit from centralized bug fixes
because usually they don’t have the permissions to install software
system-wide. Every user of the same cluster or node would still be
responsible for their own updates.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The scale is very different. If you are Red Hat, re-linking
hundreds or thousands of binaries every time there is an update in a
library is a significant burden. If you are a researcher, you deal maybe
with a dozen or two programs, and you may not have to update them
often.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Even when centralized updates are possible (e.g. if you can
request libraries to be installed centrally and then link against them),
scientists would not want them because they are directly at odds with
reproducibility.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;More efficient use of physical memory through sharing the
code&lt;/strong&gt;.&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;&lt;p&gt;In high-performance computing, the size of the libraries is
usually negligible compared to the size of the data being
processed.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;When the number of running processes is small, and they don’t
have many common dependencies, there’s not much opportunity for
sharing.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;On the other hand, sometimes multiple copies of the same
executable are run in parallel. This happens with software that is not
capable of multithreading or cannot exploit it efficiently. Well, in
this case, the OS actually can share the code across the processed
because it is exactly the same.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;When there’s little sharing of code between processes, static
linking can sometimes be &lt;em&gt;more&lt;/em&gt; memory-efficient. This is because
static linking only embeds the object files (i.e. parts of a library)
that are actually used by the application, whereas dynamic linking has
to load the entire library into memory.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Security measures like load address
randomization&lt;/strong&gt;—see above.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Some features of glibc require dynamic linking&lt;/strong&gt;.
Ulrich, by the way, was one of the core developers of glibc—just in case
you were wondering why he considers this a problem of static linking and
not a problem of glibc.&lt;/p&gt;
&lt;p&gt;Fortunately, most scientific software doesn’t perform character
conversions or go to the network. It just crunches numbers. You don’t
need dynamic linking for that.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Licensing considerations&lt;/strong&gt;. I am not a lawyer, but as
far as I can tell, this should concern you only if the software is
closed-source (or distributed under a license incompatible with GPL) and
some of those dependencies are licensed under LGPL. In that case, those
dependencies must be linked dynamically, although the other ones can
still be linked statically.&lt;/p&gt;
&lt;p&gt;I am not sure why Ulrich writes “(L)GPL”, since, to my knowledge, GPL
itself does not make a distinction between static and dynamic linking,
but I am happy to be corrected.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Tools and hacks like ltrace, LD_PRELOAD, LD_PROFILE, LD_AUDIT
don’t work&lt;/strong&gt;. Oh well.&lt;/p&gt;
&lt;h2 id=&quot;ok-how-do-i-do-this&quot;&gt;OK, how do I do this?&lt;/h2&gt;
&lt;p&gt;Unfortunately, most of the scientific software I come across is
linked dynamically by default. Otherwise, I wouldn’t be writing this
article.&lt;/p&gt;
&lt;h3 id=&quot;convincing-the-build-system&quot;&gt;Convincing the build system&lt;/h3&gt;
&lt;p&gt;Read the installation instructions. They usually can be found in a
file named README, INSTALL, or on the website. If they mention static
linking, congratulations.&lt;/p&gt;
&lt;p&gt;If not, also try looking inside the Makefile (or whatever build
system the software uses). If there is a &lt;code&gt;configure&lt;/code&gt; script,
try &lt;code&gt;./configure --help&lt;/code&gt;. There could be a target for static
linking that the author has not documented.&lt;/p&gt;
&lt;p&gt;If the build system doesn’t support static linking out of the box,
you will have to modify the linker flags. If a Makefile is well-written,
this should be as simple as &lt;code&gt;LDFLAGS=-static make&lt;/code&gt; or
&lt;code&gt;make LDFLAGS=-static&lt;/code&gt; (these &lt;a
href=&quot;http://stackoverflow.com/a/2826178/110081&quot;&gt;are different&lt;/a&gt;; try
them in this order).&lt;/p&gt;
&lt;p&gt;If that doesn’t work, edit the Makefile. Locate the rule that does
linking, i.e. produces the final executable.&lt;/p&gt;
&lt;p&gt;It usually looks like this:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb3&quot;&gt;&lt;pre
class=&quot;sourceCode makefile&quot;&gt;&lt;code class=&quot;sourceCode makefile&quot;&gt;&lt;span id=&quot;cb3-1&quot;&gt;&lt;a href=&quot;#cb3-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;dv&quot;&gt;program:&lt;/span&gt;&lt;span class=&quot;dt&quot;&gt; &lt;/span&gt;&lt;span class=&quot;ch&quot;&gt;$(&lt;/span&gt;&lt;span class=&quot;dt&quot;&gt;OBJS&lt;/span&gt;&lt;span class=&quot;ch&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-2&quot;&gt;&lt;a href=&quot;#cb3-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;er&quot;&gt;    &lt;/span&gt;gcc -o program &lt;span class=&quot;ch&quot;&gt;$(&lt;/span&gt;&lt;span class=&quot;dt&quot;&gt;OBJS&lt;/span&gt;&lt;span class=&quot;ch&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Note that &lt;code&gt;gcc&lt;/code&gt; could also be &lt;code&gt;g++&lt;/code&gt;, or
&lt;code&gt;ld&lt;/code&gt;, or hidden behind a variable such as &lt;code&gt;$(CC)&lt;/code&gt;,
&lt;code&gt;$(CXX)&lt;/code&gt;, or &lt;code&gt;$(LD)&lt;/code&gt;. The variable
&lt;code&gt;$(OBJS)&lt;/code&gt; could also be named differently, or be a literal
list of &lt;code&gt;.o&lt;/code&gt;, &lt;code&gt;.c&lt;/code&gt;, or &lt;code&gt;.cpp&lt;/code&gt; files.
But the &lt;code&gt;program&lt;/code&gt; is usually exactly the name of the final
program (or, again, a variable that expands to one).&lt;/p&gt;
&lt;p&gt;Once you located this rule, try adding a &lt;code&gt;-static&lt;/code&gt; flag to
the &lt;code&gt;gcc&lt;/code&gt; command line:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb4&quot;&gt;&lt;pre
class=&quot;sourceCode makefile&quot;&gt;&lt;code class=&quot;sourceCode makefile&quot;&gt;&lt;span id=&quot;cb4-1&quot;&gt;&lt;a href=&quot;#cb4-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;dv&quot;&gt;program:&lt;/span&gt;&lt;span class=&quot;dt&quot;&gt; &lt;/span&gt;&lt;span class=&quot;ch&quot;&gt;$(&lt;/span&gt;&lt;span class=&quot;dt&quot;&gt;OBJS&lt;/span&gt;&lt;span class=&quot;ch&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-2&quot;&gt;&lt;a href=&quot;#cb4-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;er&quot;&gt;    &lt;/span&gt;gcc -static -o program &lt;span class=&quot;ch&quot;&gt;$(&lt;/span&gt;&lt;span class=&quot;dt&quot;&gt;OBJS&lt;/span&gt;&lt;span class=&quot;ch&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;In many cases it will be enough to perform static linking.&lt;/p&gt;
&lt;p&gt;Sometimes you need to get more creative. One tool, for instance,
explicitly built itself as a shared library. This is incompatible with a
(global) &lt;code&gt;-static&lt;/code&gt; flag set as part of
&lt;code&gt;$(LDFLAGS)&lt;/code&gt;. The way I solved this was to specify a target
explicitly, i.e. &lt;code&gt;make prog1 prog2&lt;/code&gt;, so that it wouldn’t
attempt to build a dynamic library and fail.&lt;/p&gt;
&lt;h3 id=&quot;dependencies&quot;&gt;Dependencies&lt;/h3&gt;
&lt;p&gt;In order to statically link a program, you need to have its
dependencies available as static libraries. These are files names as
&lt;code&gt;libsomething.a&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;If this is a library available in your distribution:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;For Debian and derived distros (e.g. Ubuntu), static libraries
usually reside in the &lt;code&gt;libsomething-dev&lt;/code&gt; package. If you’ve
done dynamic linking of the program, you probably have this package
installed already because it also contains the header files.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;For Red Hat and derived distributions (Fedora, CentOS; not sure
about other rpm-based distros), static libraries are often placed in
separate packages named &lt;code&gt;libsomething-static&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If this is a third-party library, you’ll need to get a static version
of it or compile it from source, following the same instructions that
you are reading right now.&lt;/p&gt;
&lt;h3 id=&quot;verifying-the-result&quot;&gt;Verifying the result&lt;/h3&gt;
&lt;p&gt;How do you check that you got a static binary? Try running
&lt;code&gt;file&lt;/code&gt; and &lt;code&gt;ldd&lt;/code&gt; on it.&lt;/p&gt;
&lt;p&gt;For a dynamic binary, you’ll get something like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% ldd ./eagle 
    linux-vdso.so.1 (0x00007ffd47d87000)
    libhts.so.1 =&amp;gt; not found
    libboost_program_options.so.1.49.0 =&amp;gt; not found
    libboost_iostreams.so.1.49.0 =&amp;gt; not found
    libz.so.1 =&amp;gt; /lib64/libz.so.1 (0x00007fe77a445000)
    libopenblas.so.0 =&amp;gt; /lib64/libopenblas.so.0 (0x00007fe778133000)
    libpthread.so.0 =&amp;gt; /lib64/libpthread.so.0 (0x00007fe777f17000)
    libstdc++.so.6 =&amp;gt; /lib64/libstdc++.so.6 (0x00007fe777b90000)
    libm.so.6 =&amp;gt; /lib64/libm.so.6 (0x00007fe777886000)
    libgomp.so.1 =&amp;gt; /lib64/libgomp.so.1 (0x00007fe777658000)
    libgcc_s.so.1 =&amp;gt; /lib64/libgcc_s.so.1 (0x00007fe777441000)
    libc.so.6 =&amp;gt; /lib64/libc.so.6 (0x00007fe77707e000)
    libgfortran.so.3 =&amp;gt; /lib64/libgfortran.so.3 (0x00007fe776d4d000)
    /lib64/ld-linux-x86-64.so.2 (0x000055f7b3885000)
    libdl.so.2 =&amp;gt; /lib64/libdl.so.2 (0x00007fe776b49000)
    libquadmath.so.0 =&amp;gt; /lib64/libquadmath.so.0 (0x00007fe776908000)

% file ./eagle
./eagle: ELF 64-bit LSB executable, x86-64, version 1 (GNU/Linux), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.26, BuildID[sha1]=af18461c835d6f0209754b78c639581c67ed1443, stripped&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For a static binary, you’ll see this instead:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% ldd ./Minimac3
    not a dynamic executable

% file ./Minimac3
./Minimac3: ELF 64-bit LSB executable, x86-64, version 1 (GNU/Linux), statically linked, for GNU/Linux 2.6.26, BuildID[sha1]=edf443bb3e695b3f421b0d162ca30bb0f422c2ad, stripped&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;By the way, if &lt;code&gt;file&lt;/code&gt; says that your binary is “not
stripped”, run the &lt;code&gt;strip&lt;/code&gt; command on it:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% strip eagle&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This will significantly reduce its on-disk size and make it faster to
copy to the cluster.&lt;/p&gt;
&lt;section id=&quot;footnotes&quot; class=&quot;footnotes footnotes-end-of-document&quot;
role=&quot;doc-endnotes&quot;&gt;
&lt;hr /&gt;
&lt;ol&gt;
&lt;li id=&quot;fn1&quot;&gt;&lt;p&gt;To avoid confusion, I should note that I am talking here
about software written in compiled languages such as C, C++, or Fortran.
I am not talking about interpreted languages (Perl, Python, Ruby) or
bytecode-compiled languages (Java, Scala).&lt;a href=&quot;#fnref1&quot;
class=&quot;footnote-back&quot; role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</description>
                        <pubDate>Fri, 09 Sep 2016 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2016-09-09-static-binaries-scientific-computing</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2016-09-09-static-binaries-scientific-computing.html</guid>
                </item>
        
                <item>
                        <title>Extract the first n sequences from a FASTA file</title>
                        <description>&lt;p&gt;A &lt;a href=&quot;https://en.wikipedia.org/wiki/FASTA_format&quot;&gt;FASTA file&lt;/a&gt;
consists of a series of biological sequences (DNA, RNA, or protein). It
looks like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt;gi|173695|gb|M59083.1|AETRR16S Acetomaculum ruminis 16S ribosomal RNA
NNTAAACAAGAGAGTTCGATCCTGGCTCAGGATNAACGCTGGCGGCATGCCTAACACATGCAAGTCGAAC
GGAGTGCTTGTAGAAGCTTTTTCGGAAGTGGAAATAAGTTACTTAGTGGCGGACGGGTGAGTAACGCGTG

&amp;gt;gi|310975154|ref|NR_037018.1| Acidaminococcus fermentans strain VR4 16S ribosomal RNA gene, partial sequence
GGCTCAGGACGAACGCTGGCGGCGTGCTTAACACATGCAAGTCGAACGGAGAACTTTCTTCGGAATGTTC
TTAGTGGCGAACGGGTGAGTAACGCGTAGGCAACCTNCCCCTCTGTTGGGGACAACATTCCGAAAGGGAT&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;There probably exist dozens of python scripts to extract the first
&lt;span class=&quot;math inline&quot;&gt;\(n\)&lt;/span&gt; sequences from a FASTA file. Here
I will show an awk one-liner that performs this task, and explain how it
works.&lt;/p&gt;
&lt;p&gt;Here it is (assuming the number of sequences is stored in the
environment variable &lt;code&gt;NSEQS&lt;/code&gt;):&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb2&quot;&gt;&lt;pre
class=&quot;sourceCode bash&quot;&gt;&lt;code class=&quot;sourceCode bash&quot;&gt;&lt;span id=&quot;cb2-1&quot;&gt;&lt;a href=&quot;#cb2-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;fu&quot;&gt;awk&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;quot;/^&amp;gt;/ {n++} n&amp;gt;&lt;/span&gt;&lt;span class=&quot;va&quot;&gt;$NSEQS&lt;/span&gt;&lt;span class=&quot;st&quot;&gt; {exit} {print}&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This one-liner can read from standard input (e.g. as part of a pipe),
or you can append one or more file names to the end of the command,
e.g.&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb3&quot;&gt;&lt;pre
class=&quot;sourceCode bash&quot;&gt;&lt;code class=&quot;sourceCode bash&quot;&gt;&lt;span id=&quot;cb3-1&quot;&gt;&lt;a href=&quot;#cb3-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;fu&quot;&gt;awk&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;quot;/^&amp;gt;/ {n++} n&amp;gt;&lt;/span&gt;&lt;span class=&quot;va&quot;&gt;$NSEQS&lt;/span&gt;&lt;span class=&quot;st&quot;&gt; {exit} {print}&amp;quot;&lt;/span&gt; file.fasta&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;An awk script consists of one or more statements of the form
&lt;code&gt;pattern { actions }&lt;/code&gt;. The input is read line-by-line, and if
the current line matches the pattern, the corresponding actions are
executed.&lt;/p&gt;
&lt;p&gt;Our script consists of 3 statements:&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;/^&amp;gt;/ {n++}&lt;/code&gt; increments the counter each time a new
sequence is started. &lt;code&gt;/.../&lt;/code&gt; denotes a regular expression
pattern, and &lt;code&gt;^&amp;gt;&lt;/code&gt; is a regular expression that matches the
&lt;code&gt;&amp;gt;&lt;/code&gt; sign at the beginning of a line.&lt;/p&gt;
&lt;p&gt;An uninitialized variable in awk has the value 0, which is exactly
what we want here. If we needed some other initial value (say, 1), we
could have added a &lt;code&gt;BEGIN&lt;/code&gt; pattern like this:
&lt;code&gt;BEGIN {n=1}&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;n&amp;gt;$NSEQS {exit}&lt;/code&gt; aborts processing once the
counter reaches the desired number of sequences.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;{print}&lt;/code&gt; is an action without a pattern (and thus
matching every line), which prints every line of the input until the
script is aborted by &lt;code&gt;exit&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;A shorter and more cryptic way to write the same is&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb4&quot;&gt;&lt;pre
class=&quot;sourceCode bash&quot;&gt;&lt;code class=&quot;sourceCode bash&quot;&gt;&lt;span id=&quot;cb4-1&quot;&gt;&lt;a href=&quot;#cb4-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;fu&quot;&gt;awk&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;quot;/^&amp;gt;/ {n++} n&amp;gt;&lt;/span&gt;&lt;span class=&quot;va&quot;&gt;$NSEQS&lt;/span&gt;&lt;span class=&quot;st&quot;&gt; {exit} 1&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Here I replaced the action-without-pattern by a
pattern-without-action. The pattern &lt;code&gt;1&lt;/code&gt; (meaning “true”)
matches every line, and when the action is omitted, it is assumed to be
&lt;code&gt;{print}&lt;/code&gt;.&lt;/p&gt;
</description>
                        <pubDate>Tue, 23 Aug 2016 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2016-08-23-fasta-first-n-sequences</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2016-08-23-fasta-first-n-sequences.html</guid>
                </item>
        
                <item>
                        <title>Docker configuration on Fedora</title>
                        <description>&lt;p&gt;If you need to change the docker daemon options on Fedora, take a
look at these files:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# ls /etc/sysconfig/docker*
/etc/sysconfig/docker
/etc/sysconfig/docker-network
/etc/sysconfig/docker-storage
/etc/sysconfig/docker-storage-setup&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In my case, I needed to change the container base size, so I put the
following in &lt;code&gt;/etc/sysconfig/docker-storage&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;DOCKER_STORAGE_OPTIONS=&amp;quot;--storage-opt dm.basesize=20G&amp;quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;These files are then sourced in
&lt;code&gt;/etc/systemd/system/multi-user.target.wants/docker.service&lt;/code&gt;,
and the variables (such as &lt;code&gt;DOCKER_STORAGE_OPTIONS&lt;/code&gt;) are
passed to the docker daemon.&lt;/p&gt;
</description>
                        <pubDate>Thu, 18 Aug 2016 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2016-08-18-fedora-docker-configuration</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2016-08-18-fedora-docker-configuration.html</guid>
                </item>
        
                <item>
                        <title>Does it matter if Hask is (not) a category?</title>
                        <description>&lt;p&gt;Andrej Bauer raises a question &lt;a
href=&quot;http://math.andrej.com/2016/08/06/hask-is-not-a-category/&quot;&gt;whether
Hask is a real category&lt;/a&gt;. I think it’s a legitimate question to ask,
especially by a mathematician or programming languages researcher. But I
want to look closer at how a (probably negative) answer to this question
would affect Haskell and its community.&lt;/p&gt;
&lt;p&gt;To illustrate the fallacy of assuming blindly that Hask is a
category, Andrej tells an anecdote (which I find very funny):&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I recall a story from one of my math professors: when she was still a
doctoral student she participated as “math support” in the construction
of a small experimental nuclear reactor in Slovenia. One of the
physicsts asked her to estimate the value of the harmonic series &lt;span
class=&quot;math inline&quot;&gt;\(1+1/2+1/3+\cdots\)&lt;/span&gt; to four decimals. When
she tried to explain the series diverged, he said “that’s ok, let’s just
pretend it converges”.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Presumably here is what happened:&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;The physicists came up with a mathematical model of a nuclear
reactor.&lt;/li&gt;
&lt;li&gt;The model involved the sum of the harmonic series.&lt;/li&gt;
&lt;li&gt;Andrej’s math professor tried to explain that the series diverged
and therefore &lt;em&gt;something was wrong with the model&lt;/em&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;When we try to model a phenomenon, we should watch out for two types
of problems:&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;The model itself is erroneous.&lt;/li&gt;
&lt;li&gt;The model itself is fine; but the phenomenon we are describing does
not meet all of the model’s assumptions.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The first type of problem means that the people who built the model
couldn’t get their math right. That’s too bad. We let mathematicians to
gloss over the messy real world, to impose whatever assumptions they
want, but in return we expect a mathematically rigorous model upon which
we can build. In Andrej’s story, hopefully the math support lady helped
the physicists build a better model that didn’t rely on the convergence
of the harmonic series.&lt;/p&gt;
&lt;p&gt;But at some point the model &lt;em&gt;has&lt;/em&gt; to meet the real world; and
here, the issues are all but inevitable. We know that all models are
wrong (meaning that they don’t describe the phenomenon ideally, not that
they are erroneous) — but some are useful.&lt;/p&gt;
&lt;p&gt;Physicists, for example, often assume that they are dealing with
isolated systems, while being perfectly aware that no such system exists
(except, perhaps, for the whole universe, which would be impossible to
model accurately). Fortunately, they still manage to design working and
safe nuclear reactors!&lt;/p&gt;
&lt;p&gt;Consider Hask. Here, the abstraction is the notion of a category, and
the phenomenon is the programming language Haskell. If types and
functions of Haskell do not form a proper category, we have the second
type of modelling problem. The foundation — the category theory — is, to
the best of my knowledge, widely accepted among mathematicians as a
solid theory.&lt;/p&gt;
&lt;p&gt;Since category theory is often used to model other purely
mathematical objects, such as groups or vector spaces, mathematicians
may get used to a perfect match between the abstraction and the
phenomenon being described. Other scientists (including computer
scientists!) can rarely afford such luxury.&lt;/p&gt;
&lt;p&gt;Usefulness is the ultimate criterion by which we should judge a
model. We use monads in Haskell not because they are a cool CT concept,
but because we tried them and found that they solve many practical
problems. Comonads, which from the CT standpoint are “just” the dual of
monads, have found much fewer applications, not because we found some
kind of theoretical problems with them — we simply didn’t find that many
problems that they help address. (To be fair, we tried hard, and we did
manage to find a few.)&lt;/p&gt;
&lt;p&gt;There are people who, inspired by some category theory constructions,
come up with novel algorithms, data structures, or abstractions for
Haskell. For these discoveries to work, it is neither necessary nor
sufficient that they correspond perfectly to the original categorical
abstractions they were derived from. And as long as playing with the
“Hask category” yields helpful intuition and working programming ideas,
we are going to embrace it.&lt;/p&gt;
</description>
                        <pubDate>Sun, 07 Aug 2016 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2016-08-07-hask-category</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2016-08-07-hask-category.html</guid>
                </item>
        
                <item>
                        <title>Debugging a CUPS Forbidden error</title>
                        <description>&lt;p&gt;When I try to install a printer on a fresh Fedora 24 system through
the CUPS web interface (&lt;a href=&quot;http://localhost:631/admin/&quot;
class=&quot;uri&quot;&gt;http://localhost:631/admin/&lt;/a&gt;), I get&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Add Printer Error

Unable to add printer:

    Forbidden&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here’s the relevant part of the config file,
&lt;code&gt;/etc/cups/cupsd.conf&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;Limit CUPS-Add-Modify-Printer CUPS-Delete-Printer CUPS-Add-Modify-Class CUPS-Delete-Class CUPS-Set-Default CUPS-Get-Devices&amp;gt;
  AuthType Default
  Require user @SYSTEM
  Order deny,allow
&amp;lt;/Limit&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now look at &lt;code&gt;man cupsd.conf&lt;/code&gt; for the explanation:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Require user {user-name|@group-name} ...
     Specifies  that  an authenticated user must match one of the named
     users or be a member of one of the named groups.  The  group  name
     &amp;quot;@SYSTEM&amp;quot; corresponds to the list of groups defined by the System‐
     Group directive in the cups-files.conf(5) file.   The  group  name
     &amp;quot;@OWNER&amp;quot; corresponds to the owner of the resource, for example the
     person that submitted a print job.&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Let’s look at &lt;code&gt;/etc/cups/cups-files.conf&lt;/code&gt; and find out
what those groups are:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SystemGroup sys root&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Alright, so the solution is:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo usermod -a -G sys feuerbach&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;(where &lt;code&gt;feuerbach&lt;/code&gt; is my username).&lt;/p&gt;
&lt;p&gt;Frankly, I think it’s a bug that an admin user cannot add a printer
by default, but luckily it’s not hard to fix.&lt;/p&gt;
</description>
                        <pubDate>Fri, 08 Jul 2016 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2016-07-08-debugging-cups-forbidden-error</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2016-07-08-debugging-cups-forbidden-error.html</guid>
                </item>
        
                <item>
                        <title>Install Fedora Linux on an encrypted SSD</title>
                        <description>&lt;p&gt;I just replaced the SSD in my laptop with a bigger one and installed
a fresh Fedora Linux on it, essentially upgrading from F23 to F24.&lt;/p&gt;
&lt;p&gt;Here are a few notes which could be useful to others and myself in
the future.&lt;/p&gt;
&lt;h2 id=&quot;verifying-the-downloaded-image&quot;&gt;Verifying the downloaded
image&lt;/h2&gt;
&lt;p&gt;How do you verify the downloaded image? You verify the &lt;a
href=&quot;https://getfedora.org/verify&quot;&gt;checksum&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;How do you verify the checksum? You check its gpg signature.&lt;/p&gt;
&lt;p&gt;How do you verify the authenticity of the gpg key? You could just
check the fingerprint against the one published on the website above,
but this is hardly better than trusting the checksum, since they both
come from the same source.&lt;/p&gt;
&lt;p&gt;Here’s a better idea: if you already have a Fedora system, you have
the keys at &lt;code&gt;/etc/pki/rpm-gpg&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;In my case, I imported
&lt;code&gt;/etc/pki/rpm-gpg/RPM-GPG-KEY-fedora-24-primary&lt;/code&gt; (yes, my F23
system already contained the F24 signing keys), and was able to check
the checksum signature.&lt;/p&gt;
&lt;p&gt;This protects you against a scenario when getfedora.org is
compromised and the checksums/signatures/keys are replaced there.&lt;/p&gt;
&lt;h2 id=&quot;installing-from-a-usb-partition&quot;&gt;Installing from a USB
partition&lt;/h2&gt;
&lt;p&gt;Turned out the only optical disc in my house was damaged, and I
didn’t have a USB stick big enough to burn the Fedora image either.&lt;/p&gt;
&lt;p&gt;I did have an external USB drive with some free space on it, but it
contained a lot of data, so I couldn’t just make it one big ISO
partition.&lt;/p&gt;
&lt;p&gt;There are several instructions on how to create bootable USB
partitions, but most of them look fragile and complicated.&lt;/p&gt;
&lt;p&gt;Luckily, Fedora makes this &lt;em&gt;super&lt;/em&gt; easy.&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;Install the RPM package &lt;code&gt;livecd-tools&lt;/code&gt; (which is a
packaged version of &lt;a
href=&quot;https://github.com/rhinstaller/livecd-tools&quot;&gt;this repo&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Create a partition big enough for the ISO and format it. Unlike many
other instructions that tell you to use FAT, this one works with
ext[234] just fine.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;livecd-iso-to-disk Fedora-Workstation-Live-x86_64-24-1.2.iso /dev/sdb1&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;setting-up-disk-encryption&quot;&gt;Setting up disk encryption&lt;/h2&gt;
&lt;p&gt;I was impressed by how easy it was to set up full disk encryption. I
just checked the box “Encrypt my data” in the installer, and it used a
very sensible partitioning scheme close to what I used to set up
manually before:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Unencrypted &lt;code&gt;/boot&lt;/code&gt; partition&lt;/li&gt;
&lt;li&gt;Encrypted partition with LVM on top of it
&lt;ul&gt;
&lt;li&gt;Three logical volumes on the encrypted LVM: root,
&lt;code&gt;/home&lt;/code&gt;, and swap.&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The only thing that I had to do was to enable TRIM support:&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;For LVM: set &lt;code&gt;issue_discards = 1&lt;/code&gt; in
&lt;code&gt;/etc/lvm/lvm.conf&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;For cryptsetup: change &lt;code&gt;none&lt;/code&gt; to &lt;code&gt;discard&lt;/code&gt; in
&lt;code&gt;/etc/crypttab&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Enable weekly trims
&lt;code&gt;systemctl enable fstrim.timer &amp;amp;&amp;amp; systemctl start fstrim.timer&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
</description>
                        <pubDate>Tue, 28 Jun 2016 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2016-06-28-install-fedora-linux-on-encrypted-ssd</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2016-06-28-install-fedora-linux-on-encrypted-ssd.html</guid>
                </item>
        
                <item>
                        <title>Predicting a coin toss</title>
                        <description>&lt;p&gt;I flip a coin and it comes up heads. What is the probability it will
come up heads the next time I flip it?&lt;/p&gt;
&lt;p&gt;“Fifty percent,” you say. “The coin tosses are independent events;
the coin doesn’t have a memory.”&lt;/p&gt;
&lt;p&gt;Now I flip a coin ten times, and ten times in a row it comes up
heads. Same question: what is the probability it will come up heads the
next time?&lt;/p&gt;
&lt;p&gt;You pause for a second, if only because you are not used to seeing a
coin land heads ten times in a row.&lt;/p&gt;
&lt;p&gt;But, after some hesitation, you convince yourself that this is no
different from the first experiment. The coin still has got no memory,
and the chances are still 50-50.&lt;/p&gt;
&lt;p&gt;Or you become suspicious that something is not right with the coin.
Maybe it is biased, or maybe it has two heads and no tails. In that
case, your answer may be something like 95% for heads, where the
remaining 5% account for the chance that the coin is only somewhat
biased and tails are still possible.&lt;/p&gt;
&lt;p&gt;This sounds paradoxical: coin tosses are independent, yet the past
outcomes influence the probability of the future ones. We can explain
this by switching from frequentist to Bayesian statistics. Bayesian
statistics lets us model the coin bias (the probability of getting a
single outcome of heads) itself as a random variable, which we shall
call &lt;span class=&quot;math inline&quot;&gt;\(\theta\)&lt;/span&gt;. It is random simply
because we don’t know its true value, and not because it varies from one
experiment to another. Consequently, we will update its probability
distribution after every experiment because we gain more information,
not because it affects the coin itself.&lt;/p&gt;
&lt;div style=&quot;float: right;&quot;&gt;
&lt;p&gt;&lt;img src=&quot;/img/bayesnet.png&quot; /&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Let &lt;span class=&quot;math inline&quot;&gt;\(X_i\in\{H,T\}\)&lt;/span&gt; be the outcome
of &lt;span class=&quot;math inline&quot;&gt;\(i\)&lt;/span&gt;th toss. If we know &lt;span
class=&quot;math inline&quot;&gt;\(\theta\)&lt;/span&gt;, we automatically know the
distribution of &lt;span class=&quot;math inline&quot;&gt;\(X_i\)&lt;/span&gt;:&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;math display&quot;&gt;\[p(X_i=H|\theta)=\theta.\]&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;As before, the coin has no memory, so for any given &lt;span
class=&quot;math inline&quot;&gt;\(\theta\)&lt;/span&gt;, the tosses are independent: &lt;span
class=&quot;math inline&quot;&gt;\(p(X_i \wedge
X_j|\theta)=p(X_i|\theta)p(X_j|\theta)\)&lt;/span&gt;. But they are
independent only when conditioned on &lt;span
class=&quot;math inline&quot;&gt;\(\theta\)&lt;/span&gt;, and that resolves the paradox. If
we don’t assume that we know &lt;span
class=&quot;math inline&quot;&gt;\(\theta\)&lt;/span&gt;, then &lt;span
class=&quot;math inline&quot;&gt;\(X\)&lt;/span&gt;s &lt;em&gt;are&lt;/em&gt; dependent, because the
earlier observations affect what we know about &lt;span
class=&quot;math inline&quot;&gt;\(\theta\)&lt;/span&gt;, and &lt;span
class=&quot;math inline&quot;&gt;\(\theta\)&lt;/span&gt; affects the probability of the
future observations.&lt;/p&gt;
&lt;p&gt;A model with conditionally independent variables is called a Bayesian
network or probabilistic graphical model, and it can be represented by a
directed graph as shown on the right. The arrows point from causes to
effects, and the absence of an edge indicates conditional
independence.&lt;/p&gt;
&lt;p&gt;Based on our evidence of 10 heads in a row, Bayes’ theorem lets us
estimate the distribution of &lt;span
class=&quot;math inline&quot;&gt;\(\theta\)&lt;/span&gt;. All we need is a prior
distribution – what did we think about the coin before we tossed it?&lt;/p&gt;
&lt;p&gt;For coin tossing and other binary problems, it is customary to take
the &lt;a href=&quot;https://en.wikipedia.org/wiki/Beta_distribution&quot;&gt;Beta
distribution&lt;/a&gt; as the prior distribution, as it makes the calculations
very easy. Often such choice is justified, but in our case it would be a
terrible one. Almost all coins we encounter in our lives are fair. To
make the beta distribution centered at &lt;span
class=&quot;math inline&quot;&gt;\(\theta=0.5\)&lt;/span&gt; and low variance, we would
need to set its parameters, &lt;span class=&quot;math inline&quot;&gt;\(\alpha\)&lt;/span&gt;
and &lt;span class=&quot;math inline&quot;&gt;\(\beta\)&lt;/span&gt;, to large equal numbers.
The resulting distribution would assign non-trivial probability only to
low deviations from &lt;span class=&quot;math inline&quot;&gt;\(\theta=0.5\)&lt;/span&gt;, and
the distribution would be barely affected by our striking evidence.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/img/coin_beta.png&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Instead, let’s engineer our prior distribution from scratch.
Double-sided coins may be rare in everyday life, but they are &lt;a
href=&quot;http://www.ebay.com/bhp/two-headed-coin&quot;&gt;easy to buy on eBay&lt;/a&gt;.
When someone approaches us out of the blue and starts flipping coins,
there’s a fair chance they’ve got one of those. Still, we believe in
humanity, so let’s assign a point probability of just &lt;span
class=&quot;math inline&quot;&gt;\(1\%\)&lt;/span&gt; to &lt;span
class=&quot;math inline&quot;&gt;\(\theta=0\)&lt;/span&gt; and &lt;span
class=&quot;math inline&quot;&gt;\(\theta=1\)&lt;/span&gt;. What about biased coins, such
as coins with &lt;span class=&quot;math inline&quot;&gt;\(\theta=0.83\)&lt;/span&gt;? Turns
out &lt;a href=&quot;https://www.stat.berkeley.edu/~nolan/Papers/dice.pdf&quot;&gt;they
are unlikely to exist&lt;/a&gt;. Nevertheless, the Bayesian statistics teaches
to be reluctant to assign zero probabilities to events, since then no
amount of evidence can prove us wrong. So let’s take &lt;span
class=&quot;math inline&quot;&gt;\(0.1\%\)&lt;/span&gt; and spread it uniformly across the
interval &lt;span class=&quot;math inline&quot;&gt;\([0;1]\)&lt;/span&gt;. The remaining &lt;span
class=&quot;math inline&quot;&gt;\(97.9\%\)&lt;/span&gt; will be the probability of a fair
coin.&lt;/p&gt;
&lt;p&gt;Formally, our prior distribution over &lt;span
class=&quot;math inline&quot;&gt;\(\theta\)&lt;/span&gt; can be specified by its
probability density as&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;math display&quot;&gt;\[
p(\theta)=0.979\delta(\theta-0.5)+0.01\delta(\theta)+0.01\delta(\theta-1)+0.001,
\]&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;where &lt;span class=&quot;math inline&quot;&gt;\(\delta\)&lt;/span&gt; is the &lt;a
href=&quot;https://en.wikipedia.org/wiki/Dirac_delta_function&quot;&gt;Dirac delta
function&lt;/a&gt; used to specify point probabilities.&lt;/p&gt;
&lt;p&gt;Let &lt;span class=&quot;math inline&quot;&gt;\(D\)&lt;/span&gt; refer to the event that
&lt;span class=&quot;math inline&quot;&gt;\(X_i=H\)&lt;/span&gt;, &lt;span
class=&quot;math inline&quot;&gt;\(i=1,2,\ldots,10\)&lt;/span&gt;. Then &lt;span
class=&quot;math inline&quot;&gt;\(p(D|\theta)=\theta^{10}\)&lt;/span&gt;. By Bayes’
theorem,&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;math display&quot;&gt;\[
p(\theta|D)=\frac{p(D|\theta)p(\theta)}{\int_0^1
p(D|\theta)p(\theta)d\theta}
= \frac{\theta^{10}p(\theta)}{\int_0^1 \theta^{10}p(\theta)d\theta}.
\]&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Now we need to do a bit of calculation by hand:&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;math display&quot;&gt;\[
\begin{multline}
\int_0^1 \theta^{10}p(\theta)d\theta=0.979\cdot0.5^{10}+0.01\cdot
1^{10}+0.01 \cdot 0^{10}
+ 0.001\int_0^1 \theta^{10}d\theta
\\ = 9.56\cdot 10^{-4} + 0.01 + 9.09\cdot 10^{-5}=0.0110;
\end{multline}
\]&lt;/span&gt; &lt;span class=&quot;math display&quot;&gt;\[
p(\theta|D)=0.087\delta(\theta-0.5)+0.905\delta(\theta-1)+0.091\theta^{10}.
\]&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Thus, we are &lt;span class=&quot;math inline&quot;&gt;\(90.5\%\)&lt;/span&gt; sure that
the coin is double-headed, but we also allow &lt;span
class=&quot;math inline&quot;&gt;\(8.7\%\)&lt;/span&gt; for pure coincidence and &lt;span
class=&quot;math inline&quot;&gt;\(0.8\%\)&lt;/span&gt; for a biased coin.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/img/coin_handmade.png&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/img/coin_handmade_density.png&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Now back to our question: how likely is it that the next toss will
produce heads?&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;math display&quot;&gt;\[
\begin{multline}
p(X_{11}=H|D)
= \int_0^1 p(X_{11}=H|D,\theta)p(\theta|D)d\theta
= \int_0^1 \theta \, p(\theta|D)d\theta
\\ = 0.087\cdot 0.5+0.905\cdot 1+0.091\cdot \int_0^1\theta^{11}d\theta =
0.956.
\end{multline}
\]&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Very likely indeed. Notice, by the way, how we used the conditional
independence above to replace &lt;span
class=&quot;math inline&quot;&gt;\(p(X_{11}=H|D,\theta)\)&lt;/span&gt; with &lt;span
class=&quot;math inline&quot;&gt;\(p(X_{11}=H|\theta)=\theta\)&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;Bayesian statistics is a powerful tool, but the prior matters. Before
you reach for the conjugate prior, consider whether it actually
represents your beliefs.&lt;/p&gt;
&lt;p&gt;A couple of exercises:&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;How does our prior distribution change after a single coin toss
(either heads or tails)?&lt;/li&gt;
&lt;li&gt;How does our prior distribution change after ten heads and one
tails?&lt;/li&gt;
&lt;/ol&gt;
</description>
                        <pubDate>Tue, 14 Jun 2016 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2016-06-14-predicting-coin-toss</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2016-06-14-predicting-coin-toss.html</guid>
                </item>
        
                <item>
                        <title>Surprising reciprocity</title>
                        <description>&lt;p&gt;&lt;span class=&quot;math inline&quot;&gt;\(X\)&lt;/span&gt; and &lt;span
class=&quot;math inline&quot;&gt;\(Y\)&lt;/span&gt; are two correlated random variables
with zero mean and equal variance. If the best way to predict &lt;span
class=&quot;math inline&quot;&gt;\(Y\)&lt;/span&gt; based on &lt;span
class=&quot;math inline&quot;&gt;\(X\)&lt;/span&gt; is &lt;span class=&quot;math inline&quot;&gt;\(y = a
x\)&lt;/span&gt;, what is the best way to predict &lt;span
class=&quot;math inline&quot;&gt;\(X\)&lt;/span&gt; based on &lt;span
class=&quot;math inline&quot;&gt;\(Y\)&lt;/span&gt;?&lt;/p&gt;
&lt;p&gt;It is not &lt;span class=&quot;math inline&quot;&gt;\(x = y / a\)&lt;/span&gt;!&lt;/p&gt;
&lt;p&gt;Let’s find the &lt;span class=&quot;math inline&quot;&gt;\(a\)&lt;/span&gt; that minimizes
the mean squared error &lt;span
class=&quot;math inline&quot;&gt;\(E[(Y-aX)^2]\)&lt;/span&gt;:&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;math display&quot;&gt;\[E[(Y-aX)^2] =
E[Y^2-2aXY+a^2X^2]=(1+a^2)\mathrm{Var}(X)-2a\mathrm{Cov}(X,Y);\]&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;math display&quot;&gt;\[\frac{\partial}{\partial a}E[(Y-aX)^2] =
2a\mathrm{Var}(X)-2\mathrm{Cov}(X,Y);\]&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span
class=&quot;math display&quot;&gt;\[a=\frac{\mathrm{Cov}(X,Y)}{\mathrm{Var}(X)}=\mathrm{Corr}(X,Y).\]&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Notice that the answer, the (Pearson) correlation coefficient, is
symmetric w.r.t. &lt;span class=&quot;math inline&quot;&gt;\(X\)&lt;/span&gt; and &lt;span
class=&quot;math inline&quot;&gt;\(Y\)&lt;/span&gt;. Thus it will be the same whether we
want to predict &lt;span class=&quot;math inline&quot;&gt;\(Y\)&lt;/span&gt; based on &lt;span
class=&quot;math inline&quot;&gt;\(X\)&lt;/span&gt; or &lt;span
class=&quot;math inline&quot;&gt;\(X\)&lt;/span&gt; based on &lt;span
class=&quot;math inline&quot;&gt;\(Y\)&lt;/span&gt;!&lt;/p&gt;
&lt;p&gt;How to make sense of this? It may help to consider a couple of
special cases.&lt;/p&gt;
&lt;p&gt;First, suppose that &lt;span class=&quot;math inline&quot;&gt;\(X\)&lt;/span&gt; and &lt;span
class=&quot;math inline&quot;&gt;\(Y\)&lt;/span&gt; are perfectly correlated and you’re
trying to predict &lt;span class=&quot;math inline&quot;&gt;\(Y\)&lt;/span&gt; based on &lt;span
class=&quot;math inline&quot;&gt;\(X\)&lt;/span&gt;. Since &lt;span
class=&quot;math inline&quot;&gt;\(X\)&lt;/span&gt; is such a good predictor, just use its
value as it is (&lt;span class=&quot;math inline&quot;&gt;\(a=1\)&lt;/span&gt;).&lt;/p&gt;
&lt;p&gt;Now, suppose that &lt;span class=&quot;math inline&quot;&gt;\(X\)&lt;/span&gt; and &lt;span
class=&quot;math inline&quot;&gt;\(Y\)&lt;/span&gt; are uncorrelated. Knowing the value of
&lt;span class=&quot;math inline&quot;&gt;\(X\)&lt;/span&gt; doesn’t tell you anything about
the value of &lt;span class=&quot;math inline&quot;&gt;\(Y\)&lt;/span&gt; (as far as linear
relationships go). The best predictor you have for &lt;span
class=&quot;math inline&quot;&gt;\(Y\)&lt;/span&gt; is its mean, &lt;span
class=&quot;math inline&quot;&gt;\(0\)&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;Finally, suppose that &lt;span class=&quot;math inline&quot;&gt;\(X\)&lt;/span&gt; and
&lt;span class=&quot;math inline&quot;&gt;\(Y\)&lt;/span&gt; are &lt;em&gt;somewhat&lt;/em&gt; correlated.
The correlation coefficient is the degree to which we should trust the
value of &lt;span class=&quot;math inline&quot;&gt;\(X\)&lt;/span&gt; when predicting &lt;span
class=&quot;math inline&quot;&gt;\(Y\)&lt;/span&gt; versus sticking to &lt;span
class=&quot;math inline&quot;&gt;\(0\)&lt;/span&gt; as a conservative estimate.&lt;/p&gt;
&lt;p&gt;This is the key idea — to think about &lt;span
class=&quot;math inline&quot;&gt;\(a\)&lt;/span&gt; in &lt;span
class=&quot;math inline&quot;&gt;\(y=ax\)&lt;/span&gt; not as a degree of proportionality,
but as a degree of “trust”.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;&lt;em&gt;Added on 2020-08-21:&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;There was a related interesting discussion on twitter:&lt;/p&gt;
&lt;blockquote class=&quot;twitter-tweet&quot;&gt;
&lt;p lang=&quot;en&quot; dir=&quot;ltr&quot;&gt;
Which line do you think does a better job of predicting Y given
X?&lt;br&gt;(Hint: This is one of those days where very basic statistics
confuses the hell out of me.)&lt;br&gt;(1/n)
&lt;/p&gt;
&lt;figure&gt;
&lt;img src=&quot;/img/regression1.png&quot; width=&quot;500&quot;&gt;
&lt;/figure&gt;
— Jay Hennig (&lt;span class=&quot;citation&quot;
data-cites=&quot;jehosafet&quot;&gt;@jehosafet&lt;/span&gt;)
&lt;a href=&quot;https://twitter.com/jehosafet/status/1296074723307261952?ref_src=twsrc%5Etfw&quot;&gt;August
19, 2020&lt;/a&gt;
&lt;/blockquote&gt;
&lt;blockquote class=&quot;twitter-tweet&quot;&gt;
&lt;p lang=&quot;en&quot; dir=&quot;ltr&quot;&gt;
The answer is…black! Its rmse is 4 times lower than the red line. I keep
staring at that plot and it still blows my mind. (2/n)
&lt;/p&gt;
— Jay Hennig (&lt;span class=&quot;citation&quot;
data-cites=&quot;jehosafet&quot;&gt;@jehosafet&lt;/span&gt;)
&lt;a href=&quot;https://twitter.com/jehosafet/status/1296074724469018625?ref_src=twsrc%5Etfw&quot;&gt;August
19, 2020&lt;/a&gt;
&lt;/blockquote&gt;
&lt;blockquote class=&quot;twitter-tweet&quot;&gt;
&lt;p lang=&quot;en&quot; dir=&quot;ltr&quot;&gt;
Meanwhile, the red line is better than the black line at predicting X
given Y.&lt;br&gt;One explanation of the discrepancy is, predicting Y given X
assumes that there is no measurement noise in X, while predicting X
given Y assumes there is no measurement noise in Y.&lt;br&gt;(3/n)
&lt;/p&gt;
&lt;figure&gt;
&lt;img src=&quot;/img/regression2.png&quot; width=&quot;500&quot;&gt;
&lt;/figure&gt;
— Jay Hennig (&lt;span class=&quot;citation&quot;
data-cites=&quot;jehosafet&quot;&gt;@jehosafet&lt;/span&gt;)
&lt;a href=&quot;https://twitter.com/jehosafet/status/1296074725194641408?ref_src=twsrc%5Etfw&quot;&gt;August
19, 2020&lt;/a&gt;
&lt;/blockquote&gt;
&lt;blockquote class=&quot;twitter-tweet&quot;&gt;
&lt;p lang=&quot;en&quot; dir=&quot;ltr&quot;&gt;
The weird thing is, you are just as good at predicting X given Y as you
are at predicting Y given X. So why does the red line &lt;em&gt;look&lt;/em&gt; so
much better than the black line?&lt;br&gt;(4/n)
&lt;/p&gt;
— Jay Hennig (&lt;span class=&quot;citation&quot;
data-cites=&quot;jehosafet&quot;&gt;@jehosafet&lt;/span&gt;)
&lt;a href=&quot;https://twitter.com/jehosafet/status/1296074726876631045?ref_src=twsrc%5Etfw&quot;&gt;August
19, 2020&lt;/a&gt;
&lt;/blockquote&gt;
&lt;blockquote class=&quot;twitter-tweet&quot;&gt;
&lt;p lang=&quot;en&quot; dir=&quot;ltr&quot;&gt;
By the way, both lines have zero mean and unit variance, so the slope of
each line is equal to the pearson&apos;s correlation (ρ) between X and
Y:&lt;br&gt;black: Y = ρX&lt;br&gt;red: X = ρY&lt;br&gt;(5/n)
&lt;/p&gt;
— Jay Hennig (&lt;span class=&quot;citation&quot;
data-cites=&quot;jehosafet&quot;&gt;@jehosafet&lt;/span&gt;)
&lt;a href=&quot;https://twitter.com/jehosafet/status/1296074727644176384?ref_src=twsrc%5Etfw&quot;&gt;August
19, 2020&lt;/a&gt;
&lt;/blockquote&gt;
&lt;blockquote class=&quot;twitter-tweet&quot;&gt;
&lt;p lang=&quot;en&quot; dir=&quot;ltr&quot;&gt;
When asked to draw a regression line, my experience is people draw
something closer to the PCA line.
&lt;a href=&quot;https://t.co/978t8lcKrn&quot;&gt;https://t.co/978t8lcKrn&lt;/a&gt;
&lt;/p&gt;
— Dean Eckles (&lt;span class=&quot;citation&quot;
data-cites=&quot;deaneckles&quot;&gt;@deaneckles&lt;/span&gt;)
&lt;a href=&quot;https://twitter.com/deaneckles/status/1094314424628887552?ref_src=twsrc%5Etfw&quot;&gt;February
9, 2019&lt;/a&gt;
&lt;/blockquote&gt;
</description>
                        <pubDate>Thu, 02 Jun 2016 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2016-06-02-surprising-reciprocity</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2016-06-02-surprising-reciprocity.html</guid>
                </item>
        
                <item>
                        <title>Basic HTTP auth with Scotty</title>
                        <description>&lt;p&gt;Not so long ago, I needed to write a web app to automate the
recording of our Haskell podcast, &lt;a
href=&quot;http://bananasandlenses.net/&quot;&gt;Bananas and Lenses&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/img/recbnl.png&quot; /&gt;&lt;/p&gt;
&lt;p&gt;To build it, I chose a lightweight Haskell web framework called &lt;a
href=&quot;https://github.com/scotty-web/scotty&quot;&gt;Scotty&lt;/a&gt;. There is another
lightweight Haskell web framework called &lt;a
href=&quot;https://www.spock.li/&quot;&gt;Spock&lt;/a&gt;. Both start with the letter S and
are characters from Star Trek, and I have little hope ever being able to
tell which is which by name. I can say though that I enjoyed working
with the one I happened to pick.&lt;/p&gt;
&lt;p&gt;So, anyway, I needed to ensure that only my co-hosts and I could
access the app. In such a simple scenario, &lt;a
href=&quot;https://en.wikipedia.org/wiki/Basic_access_authentication&quot;&gt;basic
HTTP auth&lt;/a&gt; is enough. I did a quick google search for “scotty basic
auth”, but all I found was &lt;a
href=&quot;https://gist.github.com/wiz/3121322/51acc70e0757cbe9f0a0f020013306323e656928&quot;&gt;this
gist&lt;/a&gt; in which the headers are extracted by hand. Ugh.&lt;/p&gt;
&lt;p&gt;Indeed, at the time of writing, Scotty itself does not seem to
provide any shortcuts for basic auth. And yet the solution is simple and
beautiful; you just need to step back to see it. Scotty is based on WAI,
the Haskell web application interface, and doesn’t attempt to hide that
fact. On the contrary, it conveniently exposes the function&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb1&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb1-1&quot;&gt;&lt;a href=&quot;#cb1-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;middleware ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Middleware&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;ScottyM&lt;/span&gt; ()&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;which “registers” a WAI wrapper that runs on every request. And sure
enough, WAI (&lt;code&gt;wai-extra&lt;/code&gt;) &lt;a
href=&quot;https://hackage.haskell.org/package/wai-extra-3.0.15/docs/Network-Wai-Middleware-HttpAuth.html&quot;&gt;provides
an HttpAuth module&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;To put everything together, here’s a minimal password-protected
Scotty application (works with Stackage lts-5.1).&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb2&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb2-1&quot;&gt;&lt;a href=&quot;#cb2-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;{-# LANGUAGE OverloadedStrings #-}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-2&quot;&gt;&lt;a href=&quot;#cb2-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Web.Scotty&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-3&quot;&gt;&lt;a href=&quot;#cb2-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Network.Wai.Middleware.HttpAuth&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-4&quot;&gt;&lt;a href=&quot;#cb2-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Data.SecureMem&lt;/span&gt; &lt;span class=&quot;co&quot;&gt;-- for constant-time comparison&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-5&quot;&gt;&lt;a href=&quot;#cb2-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Lucid&lt;/span&gt; &lt;span class=&quot;co&quot;&gt;-- for HTML generation&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-6&quot;&gt;&lt;a href=&quot;#cb2-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-7&quot;&gt;&lt;a href=&quot;#cb2-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;password ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;SecureMem&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-8&quot;&gt;&lt;a href=&quot;#cb2-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;password &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; secureMemFromByteString &lt;span class=&quot;st&quot;&gt;&amp;quot;An7aLasi&amp;quot;&lt;/span&gt; &lt;span class=&quot;co&quot;&gt;-- https://xkcd.com/221/&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-9&quot;&gt;&lt;a href=&quot;#cb2-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-10&quot;&gt;&lt;a href=&quot;#cb2-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;main ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;IO&lt;/span&gt; ()&lt;/span&gt;
&lt;span id=&quot;cb2-11&quot;&gt;&lt;a href=&quot;#cb2-11&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;main &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; scotty &lt;span class=&quot;dv&quot;&gt;8000&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-12&quot;&gt;&lt;a href=&quot;#cb2-12&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  middleware &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; basicAuth (\u p &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; u &lt;span class=&quot;op&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;quot;user&amp;quot;&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; secureMemFromByteString p &lt;span class=&quot;op&quot;&gt;==&lt;/span&gt; password)&lt;/span&gt;
&lt;span id=&quot;cb2-13&quot;&gt;&lt;a href=&quot;#cb2-13&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;st&quot;&gt;&amp;quot;Bananas and lenses recording&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-14&quot;&gt;&lt;a href=&quot;#cb2-14&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-15&quot;&gt;&lt;a href=&quot;#cb2-15&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  get &lt;span class=&quot;st&quot;&gt;&amp;quot;/&amp;quot;&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt; html &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt; renderText &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-16&quot;&gt;&lt;a href=&quot;#cb2-16&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    doctype_&lt;/span&gt;
&lt;span id=&quot;cb2-17&quot;&gt;&lt;a href=&quot;#cb2-17&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    html_ &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-18&quot;&gt;&lt;a href=&quot;#cb2-18&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      head_ &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-19&quot;&gt;&lt;a href=&quot;#cb2-19&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;        title_ &lt;span class=&quot;st&quot;&gt;&amp;quot;Bananas and lenses recording&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-20&quot;&gt;&lt;a href=&quot;#cb2-20&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-21&quot;&gt;&lt;a href=&quot;#cb2-21&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      body_ &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; h1_ &lt;span class=&quot;st&quot;&gt;&amp;quot;Hello world!&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Two security-related points:&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;&lt;code&gt;Data.SecureMem&lt;/code&gt; is used to perform constant-time
comparison to avoid a &lt;a
href=&quot;https://en.wikipedia.org/wiki/Timing_attack&quot;&gt;timing
attack&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Ideally, the whole thing should be run over https (as the password
is submitted in clear), but this is outside of the scope of this
article.&lt;/li&gt;
&lt;/ol&gt;
</description>
                        <pubDate>Thu, 14 Apr 2016 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2016-04-14-scotty-http-basic-auth</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2016-04-14-scotty-http-basic-auth.html</guid>
                </item>
        
                <item>
                        <title>Descending sort in Haskell</title>
                        <description>&lt;p&gt;When confronted with a problem of sorting a list in descending order
in Haskell, it is tempting to reach for a “lazy” solution
&lt;code&gt;reverse . sort&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;An obvious issue with this is efficiency. While sorting in descending
order should in theory be exactly as efficient as sorting in ascending
order, the above solution requires an extra list traversal after the
sorting itself is done.&lt;/p&gt;
&lt;p&gt;This argument can be dismissed on the grounds that
&lt;code&gt;reverse&lt;/code&gt;’s run time, &lt;span
class=&quot;math inline&quot;&gt;\(\Theta(n)\)&lt;/span&gt;, is, in general, less than
&lt;code&gt;sort&lt;/code&gt;’s run time, &lt;span class=&quot;math inline&quot;&gt;\(O(n \log
n)\)&lt;/span&gt;, so it’s not a big deal. Additionally, one could argue that,
unlike more complex solutions, this one is “obviously correct”.&lt;/p&gt;
&lt;p&gt;As the rest of this article explains, &lt;em&gt;neither&lt;/em&gt; of these
claims holds universally.&lt;/p&gt;
&lt;h2 id=&quot;proper-solutions&quot;&gt;Proper solutions&lt;/h2&gt;
&lt;p&gt;Here are the two ways to sort a list in descending order that I am
aware of. Both require the more general &lt;code&gt;sortBy&lt;/code&gt; function&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb1&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb1-1&quot;&gt;&lt;a href=&quot;#cb1-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;sortBy ::&lt;/span&gt; (a &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; a &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Ordering&lt;/span&gt;) &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; [a] &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; [a]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The first argument to &lt;code&gt;sortBy&lt;/code&gt; is the comparison function.
For each pair of arguments it returns a value of type&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb2&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb2-1&quot;&gt;&lt;a href=&quot;#cb2-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Ordering&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;LT&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;EQ&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;GT&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;which describes the ordering of those arguments.&lt;/p&gt;
&lt;p&gt;The “standard” ordering is given by the &lt;code&gt;compare&lt;/code&gt; function
from the &lt;code&gt;Ord&lt;/code&gt; typeclass. Thus, &lt;code&gt;sort&lt;/code&gt; is nothing
more than&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb3&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb3-1&quot;&gt;&lt;a href=&quot;#cb3-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;fu&quot;&gt;sort&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; sortBy &lt;span class=&quot;fu&quot;&gt;compare&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The first solution to the descending sort problem exploits the fact
that, to get the opposite ordering, we can simply swap around the two
arguments to &lt;code&gt;compare&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb4&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb4-1&quot;&gt;&lt;a href=&quot;#cb4-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;sortDesc &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; sortBy (&lt;span class=&quot;fu&quot;&gt;flip&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;compare&lt;/span&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The second solution relies on the &lt;code&gt;comparing&lt;/code&gt; function
from &lt;code&gt;Data.Ord&lt;/code&gt;, which gives a particular way to compare two
values: map them to other values which are then compared using the
standard &lt;code&gt;Ord&lt;/code&gt; ordering.&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb5&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb5-1&quot;&gt;&lt;a href=&quot;#cb5-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;comparing ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Ord&lt;/span&gt; a &lt;span class=&quot;ot&quot;&gt;=&amp;gt;&lt;/span&gt; (b &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; a) &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; b &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; b &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Ordering&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This trick is often used in mathematics: to maximize a function &lt;span
class=&quot;math inline&quot;&gt;\(x\mapsto f(x)\)&lt;/span&gt;, it suffices to minimize
the function &lt;span class=&quot;math inline&quot;&gt;\(x \mapsto  -f(x)\)&lt;/span&gt;. In
Haskell, we could write&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb6&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb6-1&quot;&gt;&lt;a href=&quot;#cb6-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;sortDesc &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; sortBy (comparing &lt;span class=&quot;fu&quot;&gt;negate&lt;/span&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;and it would work most of the time. However,&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb7&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb7-1&quot;&gt;&lt;a href=&quot;#cb7-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;op&quot;&gt;&amp;gt;&lt;/span&gt; sortDesc [&lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;,&lt;span class=&quot;fu&quot;&gt;minBound&lt;/span&gt;&lt;span class=&quot;ot&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;dt&quot;&gt;Int&lt;/span&gt;]&lt;/span&gt;
&lt;span id=&quot;cb7-2&quot;&gt;&lt;a href=&quot;#cb7-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;[&lt;span class=&quot;op&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;9223372036854775808&lt;/span&gt;,&lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Besides, negation only works on numbers; what if you want to sort a
list of pairs of numbers?&lt;/p&gt;
&lt;p&gt;Fortunately, &lt;code&gt;Data.Ord&lt;/code&gt; defines a &lt;code&gt;Down&lt;/code&gt;
newtype which does exactly what we want: it reverses the ordering
between values that it’s applied to.&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb8&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb8-1&quot;&gt;&lt;a href=&quot;#cb8-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;op&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;2&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb8-2&quot;&gt;&lt;a href=&quot;#cb8-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;dt&quot;&gt;True&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb8-3&quot;&gt;&lt;a href=&quot;#cb8-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;op&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Down&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Down&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;2&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb8-4&quot;&gt;&lt;a href=&quot;#cb8-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;dt&quot;&gt;False&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Thus, the second way to sort the list in descending order is&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb9&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb9-1&quot;&gt;&lt;a href=&quot;#cb9-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;sortDesc &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; sortBy (comparing &lt;span class=&quot;dt&quot;&gt;Down&lt;/span&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;sorton&quot;&gt;sortOn&lt;/h2&gt;
&lt;p&gt;Christopher King points out that the last example may be simplified
with the help of the &lt;code&gt;sortOn&lt;/code&gt; function introduced in base 4.8
(GHC 7.10):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sortOn :: Ord b =&amp;gt; (a -&amp;gt; b) -&amp;gt; [a] -&amp;gt; [a]&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Thus, we can write&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb11&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb11-1&quot;&gt;&lt;a href=&quot;#cb11-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;sortDesc &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; sortOn &lt;span class=&quot;dt&quot;&gt;Down&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Very elegant, but let’s look at how &lt;code&gt;sortOn&lt;/code&gt; is
implemented:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb12&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb12-1&quot;&gt;&lt;a href=&quot;#cb12-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;sortOn f &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb12-2&quot;&gt;&lt;a href=&quot;#cb12-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;fu&quot;&gt;map&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;snd&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb12-3&quot;&gt;&lt;a href=&quot;#cb12-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  sortBy (comparing &lt;span class=&quot;fu&quot;&gt;fst&lt;/span&gt;) &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb12-4&quot;&gt;&lt;a href=&quot;#cb12-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;fu&quot;&gt;map&lt;/span&gt; (\x &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;let&lt;/span&gt; y &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; f x &lt;span class=&quot;kw&quot;&gt;in&lt;/span&gt; y &lt;span class=&quot;ot&quot;&gt;`seq`&lt;/span&gt; (y, x))&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This is somewhat more complicated than
&lt;code&gt;sortBy (comparing Down)&lt;/code&gt;, and it does the extra work of
first allocating &lt;span class=&quot;math inline&quot;&gt;\(n\)&lt;/span&gt; cons cells and
&lt;span class=&quot;math inline&quot;&gt;\(n\)&lt;/span&gt; tuples, then allocating another
&lt;span class=&quot;math inline&quot;&gt;\(n\)&lt;/span&gt; cons cells for the final
result.&lt;/p&gt;
&lt;p&gt;Thus, we might expect that &lt;code&gt;sortOn&lt;/code&gt; performs worse than
&lt;code&gt;sortBy&lt;/code&gt;. Let’s check our intuition:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;benchmark&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;benchmark-1&quot;&gt;&lt;a href=&quot;#benchmark-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Criterion&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;benchmark-2&quot;&gt;&lt;a href=&quot;#benchmark-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Criterion.Main&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;benchmark-3&quot;&gt;&lt;a href=&quot;#benchmark-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Data.List&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;benchmark-4&quot;&gt;&lt;a href=&quot;#benchmark-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Data.Ord&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;benchmark-5&quot;&gt;&lt;a href=&quot;#benchmark-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;benchmark-6&quot;&gt;&lt;a href=&quot;#benchmark-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;list ::&lt;/span&gt; [&lt;span class=&quot;dt&quot;&gt;Int&lt;/span&gt;]&lt;/span&gt;
&lt;span id=&quot;benchmark-7&quot;&gt;&lt;a href=&quot;#benchmark-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;list &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; [&lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;..&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;10000&lt;/span&gt;]&lt;/span&gt;
&lt;span id=&quot;benchmark-8&quot;&gt;&lt;a href=&quot;#benchmark-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;benchmark-9&quot;&gt;&lt;a href=&quot;#benchmark-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;main &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; defaultMain&lt;/span&gt;
&lt;span id=&quot;benchmark-10&quot;&gt;&lt;a href=&quot;#benchmark-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  [ bench &lt;span class=&quot;st&quot;&gt;&amp;quot;sort&amp;quot;&lt;/span&gt;   &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; nf &lt;span class=&quot;fu&quot;&gt;sort&lt;/span&gt; (&lt;span class=&quot;fu&quot;&gt;reverse&lt;/span&gt; list)&lt;/span&gt;
&lt;span id=&quot;benchmark-11&quot;&gt;&lt;a href=&quot;#benchmark-11&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  , bench &lt;span class=&quot;st&quot;&gt;&amp;quot;sortBy&amp;quot;&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; nf (sortBy (comparing &lt;span class=&quot;dt&quot;&gt;Down&lt;/span&gt;)) list&lt;/span&gt;
&lt;span id=&quot;benchmark-12&quot;&gt;&lt;a href=&quot;#benchmark-12&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  , bench &lt;span class=&quot;st&quot;&gt;&amp;quot;sortOn&amp;quot;&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; nf (sortOn &lt;span class=&quot;dt&quot;&gt;Down&lt;/span&gt;) list&lt;/span&gt;
&lt;span id=&quot;benchmark-13&quot;&gt;&lt;a href=&quot;#benchmark-13&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  ]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;(&lt;a href=&quot;#why-reverse&quot;&gt;Why reverse?&lt;/a&gt;)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;benchmarking sort
time                 134.9 μs   (134.3 μs .. 135.4 μs)
                     1.000 R²   (0.999 R² .. 1.000 R²)
mean                 134.8 μs   (134.2 μs .. 135.7 μs)
std dev              2.677 μs   (1.762 μs .. 3.956 μs)
variance introduced by outliers: 14% (moderately inflated)

benchmarking sortBy
time                 131.0 μs   (130.6 μs .. 131.4 μs)
                     1.000 R²   (1.000 R² .. 1.000 R²)
mean                 131.1 μs   (130.8 μs .. 131.4 μs)
std dev              965.1 ns   (766.5 ns .. 1.252 μs)

benchmarking sortOn
time                 940.5 μs   (928.6 μs .. 958.1 μs)
                     0.998 R²   (0.997 R² .. 0.999 R²)
mean                 950.6 μs   (940.9 μs .. 961.1 μs)
std dev              34.88 μs   (30.06 μs .. 44.19 μs)
variance introduced by outliers: 27% (moderately inflated)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As we see, &lt;code&gt;sortOn&lt;/code&gt; is 7 times slower than
&lt;code&gt;sortBy&lt;/code&gt; in this example. I also included &lt;code&gt;sort&lt;/code&gt;
in this comparison to show that &lt;code&gt;sortBy (comparing Down)&lt;/code&gt; has
no runtime overhead.&lt;/p&gt;
&lt;p&gt;There is a good reason why &lt;code&gt;sortOn&lt;/code&gt; is implemented in that
way. To quote the documentation:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;sortOn f&lt;/code&gt; is equivalent to
&lt;code&gt;sortBy (comparing f)&lt;/code&gt;, but has the performance advantage of
only evaluating f once for each element in the input list. This is
called the decorate-sort-undecorate paradigm, or Schwartzian
transform.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Indeed, if &lt;code&gt;f&lt;/code&gt; performed any non-trivial amount of work,
it would be wise to cache its results—and that’s what
&lt;code&gt;sortOn&lt;/code&gt; does.&lt;/p&gt;
&lt;p&gt;But &lt;code&gt;Down&lt;/code&gt; is a newtype constructor—it performs literally
no work at all—so the caching effort is wasted.&lt;/p&gt;
&lt;h2 id=&quot;sortwith&quot;&gt;sortWith&lt;/h2&gt;
&lt;p&gt;Yuriy Syrovetskiy points out that there is also &lt;code&gt;sortWith&lt;/code&gt;
defined in &lt;code&gt;GHC.Exts&lt;/code&gt;, which has the same type as
&lt;code&gt;sortOn&lt;/code&gt; but does no caching. So if you want to abbreviate
&lt;code&gt;sortBy (comparing Down)&lt;/code&gt;, you can say
&lt;code&gt;sortWith Down&lt;/code&gt;—but you need to import &lt;code&gt;GHC.Exts&lt;/code&gt;
first.&lt;/p&gt;
&lt;p&gt;Wonder why &lt;code&gt;sortWith&lt;/code&gt; lives in &lt;code&gt;GHC.Exts&lt;/code&gt; and
not in &lt;code&gt;Data.List&lt;/code&gt; or &lt;code&gt;Data.Ord&lt;/code&gt;? It was
originally added to aid &lt;a
href=&quot;https://downloads.haskell.org/~ghc/8.0.2/docs/html/users_guide/glasgow_exts.html#generalised-sql-like-list-comprehensions&quot;&gt;writing
SQL-like queries in Haskell&lt;/a&gt;, although I haven’t seen it used a
single time in my career.&lt;/p&gt;
&lt;h2 id=&quot;asymptotics&quot;&gt;Asymptotics&lt;/h2&gt;
&lt;div style=&quot;float:right;&quot;&gt;
&lt;p&gt;&lt;img src=&quot;/img/sort.png&quot; /&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Thanks to Haskell’s laziness in general and the careful
implementation of &lt;code&gt;sort&lt;/code&gt; in particular, &lt;code&gt;sort&lt;/code&gt; can
run in linear time when only a fixed number of first elements is
requested.&lt;/p&gt;
&lt;p&gt;So this function will return the 10 largest elements in &lt;span
class=&quot;math inline&quot;&gt;\(\Theta(n)\)&lt;/span&gt; time:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb14&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb14-1&quot;&gt;&lt;a href=&quot;#cb14-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;fu&quot;&gt;take&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;10&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt; sortBy (comparing &lt;span class=&quot;dt&quot;&gt;Down&lt;/span&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;While our “lazy” solution&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb15&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb15-1&quot;&gt;&lt;a href=&quot;#cb15-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;fu&quot;&gt;take&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;10&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;reverse&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;sort&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;(which, ironically, turns out not to be lazy enough—in the technical
sense of the word “lazy”) will run in &lt;span class=&quot;math inline&quot;&gt;\(O(n
\log n)\)&lt;/span&gt; time. This is because it requests &lt;em&gt;the last&lt;/em&gt; 10
elements of the sorted list, and in the process of doing so needs to
traverse the whole sorted list.&lt;/p&gt;
&lt;p&gt;This may appear paradoxical if considered outside of the context of
lazy evaluation. Normally, if two linear steps are performed
sequentially, the result is still linear. Here we see that adding a
linear step upgrades the overall complexity to &lt;span
class=&quot;math inline&quot;&gt;\(O(n \log n)\)&lt;/span&gt;.&lt;/p&gt;
&lt;h2 id=&quot;semantics&quot;&gt;Semantics&lt;/h2&gt;
&lt;p&gt;As I mentioned in the beginning, the simplicity of
&lt;code&gt;reverse . sort&lt;/code&gt; may be deceptive. The semantics of
&lt;code&gt;reverse . sort&lt;/code&gt; and &lt;code&gt;sortBy (comparing Down)&lt;/code&gt;
differ in a subtle way, and you &lt;em&gt;probably&lt;/em&gt; want the semantics of
&lt;code&gt;sortBy (comparing Down)&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;This is because &lt;code&gt;sort&lt;/code&gt; and &lt;code&gt;sortBy&lt;/code&gt; are
&lt;em&gt;stable&lt;/em&gt; sorting functions. They preserve the relative ordering
of “equal” elements within the list. Often this doesn’t matter because
you cannot tell equal elements apart anyway.&lt;/p&gt;
&lt;p&gt;It starts to matter when you use &lt;code&gt;comparing&lt;/code&gt; to sort
objects by a certain feature. Here we sort the list of pairs by their
first elements in descending order:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb16&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb16-1&quot;&gt;&lt;a href=&quot;#cb16-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;op&quot;&gt;&amp;gt;&lt;/span&gt; sortBy (comparing (&lt;span class=&quot;dt&quot;&gt;Down&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;fst&lt;/span&gt;)) [(&lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;,&lt;span class=&quot;ch&quot;&gt;&amp;#39;a&amp;#39;&lt;/span&gt;),(&lt;span class=&quot;dv&quot;&gt;2&lt;/span&gt;,&lt;span class=&quot;ch&quot;&gt;&amp;#39;b&amp;#39;&lt;/span&gt;),(&lt;span class=&quot;dv&quot;&gt;2&lt;/span&gt;,&lt;span class=&quot;ch&quot;&gt;&amp;#39;c&amp;#39;&lt;/span&gt;)]&lt;/span&gt;
&lt;span id=&quot;cb16-2&quot;&gt;&lt;a href=&quot;#cb16-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;[(&lt;span class=&quot;dv&quot;&gt;2&lt;/span&gt;,&lt;span class=&quot;ch&quot;&gt;&amp;#39;b&amp;#39;&lt;/span&gt;),(&lt;span class=&quot;dv&quot;&gt;2&lt;/span&gt;,&lt;span class=&quot;ch&quot;&gt;&amp;#39;c&amp;#39;&lt;/span&gt;),(&lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;,&lt;span class=&quot;ch&quot;&gt;&amp;#39;a&amp;#39;&lt;/span&gt;)]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;According to our criterion, the elements &lt;code&gt;(2,&apos;b&apos;)&lt;/code&gt; and
&lt;code&gt;(2,&apos;c&apos;)&lt;/code&gt; are considered equal, but we can see that their
ordering has been preserved.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;revese&lt;/code&gt;-based solution, on the other hand, reverses
the order of equal elements, too:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb17&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb17-1&quot;&gt;&lt;a href=&quot;#cb17-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;op&quot;&gt;&amp;gt;&lt;/span&gt; (&lt;span class=&quot;fu&quot;&gt;reverse&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt; sortBy (comparing &lt;span class=&quot;fu&quot;&gt;fst&lt;/span&gt;)) [(&lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;,&lt;span class=&quot;ch&quot;&gt;&amp;#39;a&amp;#39;&lt;/span&gt;),(&lt;span class=&quot;dv&quot;&gt;2&lt;/span&gt;,&lt;span class=&quot;ch&quot;&gt;&amp;#39;b&amp;#39;&lt;/span&gt;),(&lt;span class=&quot;dv&quot;&gt;2&lt;/span&gt;,&lt;span class=&quot;ch&quot;&gt;&amp;#39;c&amp;#39;&lt;/span&gt;)]&lt;/span&gt;
&lt;span id=&quot;cb17-2&quot;&gt;&lt;a href=&quot;#cb17-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;[(&lt;span class=&quot;dv&quot;&gt;2&lt;/span&gt;,&lt;span class=&quot;ch&quot;&gt;&amp;#39;c&amp;#39;&lt;/span&gt;),(&lt;span class=&quot;dv&quot;&gt;2&lt;/span&gt;,&lt;span class=&quot;ch&quot;&gt;&amp;#39;b&amp;#39;&lt;/span&gt;),(&lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;,&lt;span class=&quot;ch&quot;&gt;&amp;#39;a&amp;#39;&lt;/span&gt;)]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Sort with care!&lt;/p&gt;
&lt;h2 id=&quot;a-note-on-sorted-lists&quot;&gt;A note on sorted lists&lt;/h2&gt;
&lt;p&gt;The original version of this article said that &lt;code&gt;sort&lt;/code&gt; runs
in &lt;span class=&quot;math inline&quot;&gt;\(\Theta(n \log n)\)&lt;/span&gt; time. &lt;a
href=&quot;https://twitter.com/obadzz&quot;&gt;@obadzz&lt;/a&gt; &lt;a
href=&quot;https://twitter.com/obadzz/status/716648495936045056&quot;&gt;points
out&lt;/a&gt; that this is not true: &lt;code&gt;sort&lt;/code&gt; is &lt;a
href=&quot;https://github.com/ghc/ghc/blob/ghc-7.10/libraries/base/Data/OldList.hs#L828-L866&quot;&gt;implemented&lt;/a&gt;
in such a way that it will run linearly when the list is already almost
sorted in any direction. Thus I have replaced &lt;span
class=&quot;math inline&quot;&gt;\(\Theta(n \log n)\)&lt;/span&gt; with &lt;span
class=&quot;math inline&quot;&gt;\(O(n \log n)\)&lt;/span&gt; when talking about
&lt;code&gt;sort&lt;/code&gt;’s complexity.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/img/sort3.png&quot; /&gt;&lt;/p&gt;
&lt;h2 id=&quot;why-reverse&quot;&gt;Why reverse in the benchmark?&lt;/h2&gt;
&lt;p&gt;Jens Petersen asks why in the &lt;a href=&quot;#benchmark&quot;&gt;benchmark
above&lt;/a&gt; I’m comparing&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb18&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb18-1&quot;&gt;&lt;a href=&quot;#cb18-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;nf (sortBy (comparing &lt;span class=&quot;dt&quot;&gt;Down&lt;/span&gt;)) list&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;to&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb19&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb19-1&quot;&gt;&lt;a href=&quot;#cb19-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;nf &lt;span class=&quot;fu&quot;&gt;sort&lt;/span&gt; (&lt;span class=&quot;fu&quot;&gt;reverse&lt;/span&gt; list)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;I include &lt;code&gt;sort&lt;/code&gt; here as a baseline, to demonstrate that
&lt;code&gt;sortBy (comparing Down)&lt;/code&gt; does not have any significant
overhead comparing to a simple sort. But why have &lt;code&gt;reverse&lt;/code&gt;
there? Is that a typo?&lt;/p&gt;
&lt;p&gt;First of all, it’s important to understand what&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb20&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb20-1&quot;&gt;&lt;a href=&quot;#cb20-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;nf &lt;span class=&quot;fu&quot;&gt;sort&lt;/span&gt; (&lt;span class=&quot;fu&quot;&gt;reverse&lt;/span&gt; list)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;does. It may look as if it’s measuring the time it takes to reverse
and then sort a list—and why would anyone want to do such a thing?&lt;/p&gt;
&lt;p&gt;But that’s not what’s happening. In criterion, the &lt;code&gt;nf&lt;/code&gt;
combinator takes two separate values: the function (here,
&lt;code&gt;sort&lt;/code&gt;) and its argument (here, &lt;code&gt;(reverse list)&lt;/code&gt;).
Both the function and the argument are precomputed, and what’s measured
repeatedly is the time it takes to evaluate the application of the
function to its argument.&lt;/p&gt;
&lt;p&gt;The reason I measure the time it takes to sort the &lt;em&gt;reversed&lt;/em&gt;
list is to have more of an apples-to-apples comparison. If I
compared&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb21&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb21-1&quot;&gt;&lt;a href=&quot;#cb21-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;nf (sortBy (comparing &lt;span class=&quot;dt&quot;&gt;Down&lt;/span&gt;)) list&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;to&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb22&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb22-1&quot;&gt;&lt;a href=&quot;#cb22-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;nf &lt;span class=&quot;fu&quot;&gt;sort&lt;/span&gt; (&lt;span class=&quot;fu&quot;&gt;reverse&lt;/span&gt; list)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;… I would be comparing the same algorithm but on the arguments on
which it takes two different code paths: in one case it ends up
reversing the list, in the other keeping it intact. (Counterintuitively,
it looks like it’s faster for &lt;code&gt;sort&lt;/code&gt;/&lt;code&gt;sortBy&lt;/code&gt; to
reverse the list than to keep it as-is.)&lt;/p&gt;
&lt;p&gt;Therefore, by reversing the argument, I make sure that in all three
cases (&lt;code&gt;sort&lt;/code&gt;, &lt;code&gt;sortBy&lt;/code&gt;, and &lt;code&gt;sortOn&lt;/code&gt;)
the input list “looks” the same as seen by the comparison function, and
in all three cases the sorting algorithm needs to reverse the list.&lt;/p&gt;
</description>
                        <pubDate>Sat, 02 Apr 2016 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2016-04-02-descending-sort-haskell</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2016-04-02-descending-sort-haskell.html</guid>
                </item>
        
                <item>
                        <title>rank vs. order in R</title>
                        <description>&lt;p&gt;A lot of people (myself included) get confused when they are first
confronted with &lt;a
href=&quot;https://stat.ethz.ch/R-manual/R-devel/library/base/html/rank.html&quot;&gt;&lt;code&gt;rank&lt;/code&gt;&lt;/a&gt;
and &lt;a
href=&quot;https://stat.ethz.ch/R-manual/R-devel/library/base/html/order.html&quot;&gt;&lt;code&gt;order&lt;/code&gt;&lt;/a&gt;
functions in R. Not only do the descriptions of these functions sound
related (they both have to do with how a vector’s elements are arranged
when the vector is sorted), but their return values may seem identical
at first.&lt;/p&gt;
&lt;p&gt;Here’s how my first encounter with these two functions went. The
easiest thing is to see how they work on already sorted vectors:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb1&quot;&gt;&lt;pre class=&quot;sourceCode r&quot;&gt;&lt;code class=&quot;sourceCode r&quot;&gt;&lt;span id=&quot;cb1-1&quot;&gt;&lt;a href=&quot;#cb1-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;sc&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;rank&lt;/span&gt;(&lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;sc&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;3&lt;/span&gt;)&lt;/span&gt;
&lt;span id=&quot;cb1-2&quot;&gt;&lt;a href=&quot;#cb1-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;[&lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;] &lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;3&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-3&quot;&gt;&lt;a href=&quot;#cb1-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;sc&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;order&lt;/span&gt;(&lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;sc&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;3&lt;/span&gt;)&lt;/span&gt;
&lt;span id=&quot;cb1-4&quot;&gt;&lt;a href=&quot;#cb1-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;[&lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;] &lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;3&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Fair enough. Now let’s try a reversed sorted vector.&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb2&quot;&gt;&lt;pre class=&quot;sourceCode r&quot;&gt;&lt;code class=&quot;sourceCode r&quot;&gt;&lt;span id=&quot;cb2-1&quot;&gt;&lt;a href=&quot;#cb2-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;sc&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;rank&lt;/span&gt;(&lt;span class=&quot;fu&quot;&gt;rev&lt;/span&gt;(&lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;sc&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;3&lt;/span&gt;))&lt;/span&gt;
&lt;span id=&quot;cb2-2&quot;&gt;&lt;a href=&quot;#cb2-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;[&lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;] &lt;span class=&quot;dv&quot;&gt;3&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-3&quot;&gt;&lt;a href=&quot;#cb2-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;sc&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;order&lt;/span&gt;(&lt;span class=&quot;fu&quot;&gt;rev&lt;/span&gt;(&lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;sc&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;3&lt;/span&gt;))&lt;/span&gt;
&lt;span id=&quot;cb2-4&quot;&gt;&lt;a href=&quot;#cb2-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;[&lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;] &lt;span class=&quot;dv&quot;&gt;3&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Uhm, ok. I guess I should try to shuffle the elements.&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb3&quot;&gt;&lt;pre class=&quot;sourceCode r&quot;&gt;&lt;code class=&quot;sourceCode r&quot;&gt;&lt;span id=&quot;cb3-1&quot;&gt;&lt;a href=&quot;#cb3-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;sc&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;rank&lt;/span&gt;(&lt;span class=&quot;fu&quot;&gt;c&lt;/span&gt;(&lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;,&lt;span class=&quot;dv&quot;&gt;3&lt;/span&gt;,&lt;span class=&quot;dv&quot;&gt;2&lt;/span&gt;))&lt;/span&gt;
&lt;span id=&quot;cb3-2&quot;&gt;&lt;a href=&quot;#cb3-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;[&lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;] &lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;3&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;2&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-3&quot;&gt;&lt;a href=&quot;#cb3-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;sc&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;order&lt;/span&gt;(&lt;span class=&quot;fu&quot;&gt;c&lt;/span&gt;(&lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;,&lt;span class=&quot;dv&quot;&gt;3&lt;/span&gt;,&lt;span class=&quot;dv&quot;&gt;2&lt;/span&gt;))&lt;/span&gt;
&lt;span id=&quot;cb3-4&quot;&gt;&lt;a href=&quot;#cb3-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;[&lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;] &lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;3&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;2&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Perhaps 3 elements is too few.&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb4&quot;&gt;&lt;pre class=&quot;sourceCode r&quot;&gt;&lt;code class=&quot;sourceCode r&quot;&gt;&lt;span id=&quot;cb4-1&quot;&gt;&lt;a href=&quot;#cb4-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;sc&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;rank&lt;/span&gt;(&lt;span class=&quot;fu&quot;&gt;c&lt;/span&gt;(&lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;,&lt;span class=&quot;dv&quot;&gt;3&lt;/span&gt;,&lt;span class=&quot;dv&quot;&gt;2&lt;/span&gt;,&lt;span class=&quot;dv&quot;&gt;4&lt;/span&gt;))&lt;/span&gt;
&lt;span id=&quot;cb4-2&quot;&gt;&lt;a href=&quot;#cb4-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;[&lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;] &lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;3&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;4&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-3&quot;&gt;&lt;a href=&quot;#cb4-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;sc&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;order&lt;/span&gt;(&lt;span class=&quot;fu&quot;&gt;c&lt;/span&gt;(&lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;,&lt;span class=&quot;dv&quot;&gt;3&lt;/span&gt;,&lt;span class=&quot;dv&quot;&gt;2&lt;/span&gt;,&lt;span class=&quot;dv&quot;&gt;4&lt;/span&gt;))&lt;/span&gt;
&lt;span id=&quot;cb4-4&quot;&gt;&lt;a href=&quot;#cb4-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;[&lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;] &lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;3&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;4&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Or maybe I shouldn’t use small consequtive numbers?&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb5&quot;&gt;&lt;pre class=&quot;sourceCode r&quot;&gt;&lt;code class=&quot;sourceCode r&quot;&gt;&lt;span id=&quot;cb5-1&quot;&gt;&lt;a href=&quot;#cb5-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;sc&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;rank&lt;/span&gt;(&lt;span class=&quot;fu&quot;&gt;c&lt;/span&gt;(&lt;span class=&quot;dv&quot;&gt;10&lt;/span&gt;,&lt;span class=&quot;dv&quot;&gt;30&lt;/span&gt;,&lt;span class=&quot;dv&quot;&gt;20&lt;/span&gt;,&lt;span class=&quot;dv&quot;&gt;40&lt;/span&gt;))&lt;/span&gt;
&lt;span id=&quot;cb5-2&quot;&gt;&lt;a href=&quot;#cb5-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;[&lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;] &lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;3&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;4&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-3&quot;&gt;&lt;a href=&quot;#cb5-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;sc&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;order&lt;/span&gt;(&lt;span class=&quot;fu&quot;&gt;c&lt;/span&gt;(&lt;span class=&quot;dv&quot;&gt;10&lt;/span&gt;,&lt;span class=&quot;dv&quot;&gt;30&lt;/span&gt;,&lt;span class=&quot;dv&quot;&gt;20&lt;/span&gt;,&lt;span class=&quot;dv&quot;&gt;40&lt;/span&gt;))&lt;/span&gt;
&lt;span id=&quot;cb5-4&quot;&gt;&lt;a href=&quot;#cb5-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;[&lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;] &lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;3&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;4&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;So, where is the difference, and why is it so hard to find?&lt;/p&gt;
&lt;h2 id=&quot;definitions&quot;&gt;Definitions&lt;/h2&gt;
&lt;p&gt;Let’s say we have a sequence of numbers &lt;span
class=&quot;math inline&quot;&gt;\(a_1, a_2, \ldots, a_n\)&lt;/span&gt;. For simplicity,
assume that all numbers are distinct.&lt;/p&gt;
&lt;p&gt;Sorting this sequence yields a permutation &lt;span
class=&quot;math inline&quot;&gt;\(a_{s_1},a_{s_2},\ldots,a_{s_n}\)&lt;/span&gt;, where
&lt;span class=&quot;math inline&quot;&gt;\(s_1\)&lt;/span&gt; is the index of the smallest
&lt;span class=&quot;math inline&quot;&gt;\(a_i\)&lt;/span&gt;, &lt;span
class=&quot;math inline&quot;&gt;\(s_2\)&lt;/span&gt; is the index of the second smallest
one, and so on, up to &lt;span class=&quot;math inline&quot;&gt;\(s_n\)&lt;/span&gt;, the
index of the greatest &lt;span class=&quot;math inline&quot;&gt;\(a_i\)&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;The sequence &lt;span class=&quot;math inline&quot;&gt;\(s_1,s_2,\ldots,s_n\)&lt;/span&gt;
is what the &lt;code&gt;order&lt;/code&gt; function returns. If &lt;code&gt;a&lt;/code&gt; is a
vector, &lt;code&gt;a[order(a)]&lt;/code&gt; is the same vector but sorted in the
ascending order.&lt;/p&gt;
&lt;p&gt;Now, the &lt;em&gt;rank&lt;/em&gt; of an element is its position in the sorted
vector. The &lt;code&gt;rank&lt;/code&gt; function returns a vector &lt;span
class=&quot;math inline&quot;&gt;\(t_1,\ldots,t_n\)&lt;/span&gt;, where &lt;span
class=&quot;math inline&quot;&gt;\(t_i\)&lt;/span&gt; is the position of &lt;span
class=&quot;math inline&quot;&gt;\(a_i\)&lt;/span&gt; within &lt;span
class=&quot;math inline&quot;&gt;\(a_{s_1},\ldots,a_{s_n}\)&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;It is hard to tell in general where &lt;span
class=&quot;math inline&quot;&gt;\(a_i\)&lt;/span&gt; will occur among &lt;span
class=&quot;math inline&quot;&gt;\(a_{s_1},\ldots,a_{s_n}\)&lt;/span&gt;; but we know
exactly where &lt;span class=&quot;math inline&quot;&gt;\(a_{s_k}\)&lt;/span&gt; occurs: on
the &lt;span class=&quot;math inline&quot;&gt;\(k\)&lt;/span&gt;th position! Thus, &lt;span
class=&quot;math inline&quot;&gt;\(t_{s_k}=k\)&lt;/span&gt;.&lt;/p&gt;
&lt;h2 id=&quot;inverse-and-involutive-permutations&quot;&gt;Inverse and involutive
permutations&lt;/h2&gt;
&lt;p&gt;Considered as functions (&lt;a
href=&quot;https://en.wikipedia.org/wiki/Permutation&quot;&gt;permutations&lt;/a&gt;),
&lt;span class=&quot;math inline&quot;&gt;\(s\)&lt;/span&gt; and &lt;span
class=&quot;math inline&quot;&gt;\(t\)&lt;/span&gt; are &lt;em&gt;inverse&lt;/em&gt; (&lt;span
class=&quot;math inline&quot;&gt;\(s\circ t = t\circ s = id\)&lt;/span&gt;). Or, expressed
in R:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb6&quot;&gt;&lt;pre class=&quot;sourceCode r&quot;&gt;&lt;code class=&quot;sourceCode r&quot;&gt;&lt;span id=&quot;cb6-1&quot;&gt;&lt;a href=&quot;#cb6-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;sc&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;all&lt;/span&gt;((&lt;span class=&quot;fu&quot;&gt;rank&lt;/span&gt;(a))[&lt;span class=&quot;fu&quot;&gt;order&lt;/span&gt;(a)] &lt;span class=&quot;sc&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;sc&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;length&lt;/span&gt;(a))&lt;/span&gt;
&lt;span id=&quot;cb6-2&quot;&gt;&lt;a href=&quot;#cb6-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;[&lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;] &lt;span class=&quot;cn&quot;&gt;TRUE&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-3&quot;&gt;&lt;a href=&quot;#cb6-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;sc&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;all&lt;/span&gt;((&lt;span class=&quot;fu&quot;&gt;order&lt;/span&gt;(a))[&lt;span class=&quot;fu&quot;&gt;rank&lt;/span&gt;(a)] &lt;span class=&quot;sc&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;sc&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;length&lt;/span&gt;(a))&lt;/span&gt;
&lt;span id=&quot;cb6-4&quot;&gt;&lt;a href=&quot;#cb6-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;[&lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;] &lt;span class=&quot;cn&quot;&gt;TRUE&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;In the beginning, we saw several examples of &lt;span
class=&quot;math inline&quot;&gt;\(s\)&lt;/span&gt; and &lt;span
class=&quot;math inline&quot;&gt;\(t\)&lt;/span&gt; being the same, i.e. &lt;span
class=&quot;math inline&quot;&gt;\(s\circ s = id\)&lt;/span&gt;. Such functions are called
&lt;a
href=&quot;https://en.wikipedia.org/wiki/Involution_%28mathematics%29&quot;&gt;&lt;em&gt;involutions&lt;/em&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;That our examples led to involutive permutations was a coincidence,
but not an unlikely one. Indeed, for &lt;span
class=&quot;math inline&quot;&gt;\(n=2\)&lt;/span&gt;, all two permutations are
involutions: &lt;span class=&quot;math inline&quot;&gt;\(1,2\)&lt;/span&gt; and &lt;span
class=&quot;math inline&quot;&gt;\(2,1\)&lt;/span&gt;. In general, permutations &lt;span
class=&quot;math inline&quot;&gt;\(1,2,\ldots,n\)&lt;/span&gt; and &lt;span
class=&quot;math inline&quot;&gt;\(n,n-1,\ldots,1\)&lt;/span&gt; will be involutions
&lt;em&gt;for any&lt;/em&gt; &lt;span class=&quot;math inline&quot;&gt;\(n\)&lt;/span&gt;; for &lt;span
class=&quot;math inline&quot;&gt;\(n=2\)&lt;/span&gt; it just happens so that there are no
others.&lt;/p&gt;
&lt;p&gt;For &lt;span class=&quot;math inline&quot;&gt;\(n=3\)&lt;/span&gt;, we have a total of
&lt;span class=&quot;math inline&quot;&gt;\(3!=6\)&lt;/span&gt; permutations. Two of them, the
identical permutation and its opposite, are involutions as discussed
above. Out of the remaining 4, half are involutions (&lt;span
class=&quot;math inline&quot;&gt;\(1,3,2\)&lt;/span&gt; and &lt;span
class=&quot;math inline&quot;&gt;\(2,1,3\)&lt;/span&gt;) and the other half are not (&lt;span
class=&quot;math inline&quot;&gt;\(2,3,1\)&lt;/span&gt; and &lt;span
class=&quot;math inline&quot;&gt;\(3,1,2\)&lt;/span&gt;). So, for &lt;span
class=&quot;math inline&quot;&gt;\(n=3\)&lt;/span&gt;, the odds are 2 to 1 that
&lt;code&gt;order&lt;/code&gt; and &lt;code&gt;rank&lt;/code&gt; will yield the same result.&lt;/p&gt;
&lt;p&gt;Any permutation consists of one or more &lt;em&gt;cycles&lt;/em&gt;. The
non-involutive &lt;span class=&quot;math inline&quot;&gt;\(2,3,1\)&lt;/span&gt; and &lt;span
class=&quot;math inline&quot;&gt;\(3,1,2\)&lt;/span&gt; are cycles of their own, while
&lt;span class=&quot;math inline&quot;&gt;\(1,3,2\)&lt;/span&gt; consists of two cycles: &lt;span
class=&quot;math inline&quot;&gt;\((1)\)&lt;/span&gt; of size 1 and &lt;span
class=&quot;math inline&quot;&gt;\((2\;3)\)&lt;/span&gt; of size 2. The sum of cycle sizes,
of course, must equal &lt;span class=&quot;math inline&quot;&gt;\(n\)&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;It is not hard to see that a permutation is involutive if and only if
all its cycles are of sizes 1 or 2. This explains why involutions are so
common for &lt;span class=&quot;math inline&quot;&gt;\(n=3\)&lt;/span&gt;; there’s not much
room for longer cycles. For larger &lt;span
class=&quot;math inline&quot;&gt;\(n\)&lt;/span&gt;, however, the situation changes, and
getting at least one cycle longer than 2 becomes inevitable as &lt;span
class=&quot;math inline&quot;&gt;\(n\)&lt;/span&gt; grows.&lt;/p&gt;
&lt;div style=&quot;float: right;&quot;&gt;
&lt;p&gt;&lt;img src=&quot;/img/involutions.png&quot; /&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;We can easily compute the odds that &lt;code&gt;rank&lt;/code&gt; and
&lt;code&gt;order&lt;/code&gt; coincide for a random permutation of size &lt;span
class=&quot;math inline&quot;&gt;\(n\)&lt;/span&gt;. If &lt;span
class=&quot;math inline&quot;&gt;\(a\)&lt;/span&gt; is itself a permutation (e.g. if its
generated by &lt;code
class=&quot;sourceCode r&quot;&gt;&lt;span class=&quot;fu&quot;&gt;sample&lt;/span&gt;(n)&lt;/code&gt; in R),
then &lt;span class=&quot;math inline&quot;&gt;\(t=a\)&lt;/span&gt;. All we need to do is to
figure out how many involutions there are among &lt;span
class=&quot;math inline&quot;&gt;\(n!\)&lt;/span&gt; permutations of size &lt;span
class=&quot;math inline&quot;&gt;\(n\)&lt;/span&gt;. That number is &lt;a
href=&quot;http://mathworld.wolfram.com/PermutationInvolution.html&quot;&gt;given
by&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;math display&quot;&gt;\[
I(n)=1+\sum_{k=0}^{\lfloor(n-1)/2\rfloor} \frac{1}{(k+1)!}
       \prod_{i=0}^k \binom{n-2i}{2}
\]&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;(hint: &lt;span class=&quot;math inline&quot;&gt;\(k+1\)&lt;/span&gt; is the number of
cycles of size 2).&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb7&quot;&gt;&lt;pre class=&quot;sourceCode r&quot;&gt;&lt;code class=&quot;sourceCode r&quot;&gt;&lt;span id=&quot;cb7-1&quot;&gt;&lt;a href=&quot;#cb7-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;I &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;cf&quot;&gt;function&lt;/span&gt;(nn) {&lt;/span&gt;
&lt;span id=&quot;cb7-2&quot;&gt;&lt;a href=&quot;#cb7-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;fu&quot;&gt;sapply&lt;/span&gt;(nn, &lt;span class=&quot;cf&quot;&gt;function&lt;/span&gt;(n) {&lt;/span&gt;
&lt;span id=&quot;cb7-3&quot;&gt;&lt;a href=&quot;#cb7-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;sc&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;sum&lt;/span&gt;(&lt;span class=&quot;fu&quot;&gt;sapply&lt;/span&gt;(&lt;span class=&quot;dv&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;sc&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;floor&lt;/span&gt;((n&lt;span class=&quot;dv&quot;&gt;-1&lt;/span&gt;)&lt;span class=&quot;sc&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;2&lt;/span&gt;),&lt;/span&gt;
&lt;span id=&quot;cb7-4&quot;&gt;&lt;a href=&quot;#cb7-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;cf&quot;&gt;function&lt;/span&gt;(k) {&lt;/span&gt;
&lt;span id=&quot;cb7-5&quot;&gt;&lt;a href=&quot;#cb7-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;        &lt;span class=&quot;fu&quot;&gt;prod&lt;/span&gt;(&lt;span class=&quot;fu&quot;&gt;sapply&lt;/span&gt;(&lt;span class=&quot;dv&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;sc&quot;&gt;:&lt;/span&gt;k, &lt;span class=&quot;cf&quot;&gt;function&lt;/span&gt;(i) {&lt;/span&gt;
&lt;span id=&quot;cb7-6&quot;&gt;&lt;a href=&quot;#cb7-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;          &lt;span class=&quot;fu&quot;&gt;choose&lt;/span&gt;(n&lt;span class=&quot;dv&quot;&gt;-2&lt;/span&gt;&lt;span class=&quot;sc&quot;&gt;*&lt;/span&gt;i,&lt;span class=&quot;dv&quot;&gt;2&lt;/span&gt;)&lt;/span&gt;
&lt;span id=&quot;cb7-7&quot;&gt;&lt;a href=&quot;#cb7-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;        })) &lt;span class=&quot;sc&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;factorial&lt;/span&gt;(k&lt;span class=&quot;sc&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;)&lt;/span&gt;
&lt;span id=&quot;cb7-8&quot;&gt;&lt;a href=&quot;#cb7-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      }))&lt;/span&gt;
&lt;span id=&quot;cb7-9&quot;&gt;&lt;a href=&quot;#cb7-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  })&lt;/span&gt;
&lt;span id=&quot;cb7-10&quot;&gt;&lt;a href=&quot;#cb7-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;}&lt;/span&gt;
&lt;span id=&quot;cb7-11&quot;&gt;&lt;a href=&quot;#cb7-11&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb7-12&quot;&gt;&lt;a href=&quot;#cb7-12&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;n &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;sc&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;10&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb7-13&quot;&gt;&lt;a href=&quot;#cb7-13&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;fu&quot;&gt;plot&lt;/span&gt;(&lt;span class=&quot;fu&quot;&gt;I&lt;/span&gt;(n)&lt;span class=&quot;sc&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;factorial&lt;/span&gt;(n) &lt;span class=&quot;sc&quot;&gt;~&lt;/span&gt; n,&lt;span class=&quot;at&quot;&gt;type=&lt;/span&gt;&lt;span class=&quot;st&quot;&gt;&amp;#39;b&amp;#39;&lt;/span&gt;)&lt;/span&gt;
&lt;span id=&quot;cb7-14&quot;&gt;&lt;a href=&quot;#cb7-14&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;fu&quot;&gt;grid&lt;/span&gt;(&lt;span class=&quot;at&quot;&gt;col=&lt;/span&gt;&lt;span class=&quot;fu&quot;&gt;rgb&lt;/span&gt;(&lt;span class=&quot;fl&quot;&gt;0.3&lt;/span&gt;,&lt;span class=&quot;fl&quot;&gt;0.3&lt;/span&gt;,&lt;span class=&quot;fl&quot;&gt;0.7&lt;/span&gt;))&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
</description>
                        <pubDate>Sat, 19 Mar 2016 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2016-03-19-rank-vs-order-r</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2016-03-19-rank-vs-order-r.html</guid>
                </item>
        
                <item>
                        <title>Reducing boilerplate in finally tagless style</title>
                        <description>&lt;h2 id=&quot;introduction&quot;&gt;Introduction&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;http://okmij.org/ftp/tagless-final/&quot;&gt;Typed Tagless&lt;/a&gt;,
a.k.a tagless-final or finally tagless, is an approach to embedding DSLs
and modeling data in general, advocated by Oleg Kiselyov. Instead of
defining a set of algebraic data types to describe data or terms, thus
focusing on how data is &lt;em&gt;constructed&lt;/em&gt;, the approach focuses on
data &lt;em&gt;consumption&lt;/em&gt;, defining a canonical eliminator for every
constructor that we would otherwise define.&lt;/p&gt;
&lt;p&gt;For instance, instead of defining lists as&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb1&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb1-1&quot;&gt;&lt;a href=&quot;#cb1-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;List&lt;/span&gt; a &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Nil&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Cons&lt;/span&gt; a (&lt;span class=&quot;dt&quot;&gt;List&lt;/span&gt; a)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;we would define a class&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb2&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb2-1&quot;&gt;&lt;a href=&quot;#cb2-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;List&lt;/span&gt; rep a &lt;span class=&quot;kw&quot;&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-2&quot;&gt;&lt;a href=&quot;#cb2-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;  nil ::&lt;/span&gt; rep&lt;/span&gt;
&lt;span id=&quot;cb2-3&quot;&gt;&lt;a href=&quot;#cb2-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;  cons ::&lt;/span&gt; a &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; rep &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; rep&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;which of course corresponds to the Böhm-Berarducci (or Church)
encoding of the above algebraic type.&lt;/p&gt;
&lt;p&gt;Oleg has written extensively on the merits of this approach. In this
article, I want to discuss a certain aspect of writing transformations
in the finally tagless style.&lt;/p&gt;
&lt;h2 id=&quot;the-use-case-language-integrated-query&quot;&gt;The use case:
language-integrated query&lt;/h2&gt;
&lt;p&gt;Oleg, together with Kenichi Suzuki and Yukiyoshi Kameyama, have
published a paper &lt;a
href=&quot;http://okmij.org/ftp/meta-programming/quel.pdf&quot;&gt;Finally,
Safely-Extensible and Efficient Language-Integrated Query&lt;/a&gt;. In this
paper, they employ the finally tagless approach to embed, optimize, and
interpret SQL queries in OCaml.&lt;/p&gt;
&lt;p&gt;Here are some excerpts from their &lt;a
href=&quot;http://logic.cs.tsukuba.ac.jp/~ken/quel/&quot;&gt;OCaml code&lt;/a&gt;:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb3&quot;&gt;&lt;pre
class=&quot;sourceCode ocaml&quot;&gt;&lt;code class=&quot;sourceCode ocaml&quot;&gt;&lt;span id=&quot;cb3-1&quot;&gt;&lt;a href=&quot;#cb3-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;co&quot;&gt;(* Base Symantics *)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-2&quot;&gt;&lt;a href=&quot;#cb3-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;module&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;type&lt;/span&gt; Symantics_base = &lt;span class=&quot;kw&quot;&gt;sig&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-3&quot;&gt;&lt;a href=&quot;#cb3-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  ...&lt;/span&gt;
&lt;span id=&quot;cb3-4&quot;&gt;&lt;a href=&quot;#cb3-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;co&quot;&gt;(* lambda abstract *)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-5&quot;&gt;&lt;a href=&quot;#cb3-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;val&lt;/span&gt; lam     : (&amp;#39;a repr -&amp;gt; &amp;#39;b repr) -&amp;gt; (&amp;#39;a -&amp;gt; &amp;#39;b) repr&lt;/span&gt;
&lt;span id=&quot;cb3-6&quot;&gt;&lt;a href=&quot;#cb3-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;co&quot;&gt;(* application *)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-7&quot;&gt;&lt;a href=&quot;#cb3-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;val&lt;/span&gt; app     : (&amp;#39;a -&amp;gt; &amp;#39;b) repr -&amp;gt; &amp;#39;a repr -&amp;gt; &amp;#39;b repr&lt;/span&gt;
&lt;span id=&quot;cb3-8&quot;&gt;&lt;a href=&quot;#cb3-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  ...&lt;/span&gt;
&lt;span id=&quot;cb3-9&quot;&gt;&lt;a href=&quot;#cb3-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;end&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-10&quot;&gt;&lt;a href=&quot;#cb3-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-11&quot;&gt;&lt;a href=&quot;#cb3-11&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;co&quot;&gt;(* Symantics with list operations *)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-12&quot;&gt;&lt;a href=&quot;#cb3-12&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;module&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;type&lt;/span&gt; SymanticsL = &lt;span class=&quot;kw&quot;&gt;sig&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-13&quot;&gt;&lt;a href=&quot;#cb3-13&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;include&lt;/span&gt; Symantics&lt;/span&gt;
&lt;span id=&quot;cb3-14&quot;&gt;&lt;a href=&quot;#cb3-14&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-15&quot;&gt;&lt;a href=&quot;#cb3-15&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;co&quot;&gt;(* comprehension *)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-16&quot;&gt;&lt;a href=&quot;#cb3-16&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;val&lt;/span&gt; foreach : (&lt;span class=&quot;dt&quot;&gt;unit&lt;/span&gt; -&amp;gt; &amp;#39;a &lt;span class=&quot;dt&quot;&gt;list&lt;/span&gt; repr) -&amp;gt;&lt;/span&gt;
&lt;span id=&quot;cb3-17&quot;&gt;&lt;a href=&quot;#cb3-17&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;                (&amp;#39;a repr -&amp;gt;  &amp;#39;b &lt;span class=&quot;dt&quot;&gt;list&lt;/span&gt; repr) -&amp;gt; &amp;#39;b &lt;span class=&quot;dt&quot;&gt;list&lt;/span&gt; repr&lt;/span&gt;
&lt;span id=&quot;cb3-18&quot;&gt;&lt;a href=&quot;#cb3-18&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;co&quot;&gt;(* condition *)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-19&quot;&gt;&lt;a href=&quot;#cb3-19&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;val&lt;/span&gt; where   :  &lt;span class=&quot;dt&quot;&gt;bool&lt;/span&gt; repr -&amp;gt; (&lt;span class=&quot;dt&quot;&gt;unit&lt;/span&gt; -&amp;gt; &amp;#39;a &lt;span class=&quot;dt&quot;&gt;list&lt;/span&gt; repr) -&amp;gt; &amp;#39;a &lt;span class=&quot;dt&quot;&gt;list&lt;/span&gt; repr&lt;/span&gt;
&lt;span id=&quot;cb3-20&quot;&gt;&lt;a href=&quot;#cb3-20&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;co&quot;&gt;(* yield singleton list *)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-21&quot;&gt;&lt;a href=&quot;#cb3-21&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;val&lt;/span&gt; yield   : &amp;#39;a repr -&amp;gt;  &amp;#39;a &lt;span class=&quot;dt&quot;&gt;list&lt;/span&gt; repr&lt;/span&gt;
&lt;span id=&quot;cb3-22&quot;&gt;&lt;a href=&quot;#cb3-22&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;co&quot;&gt;(* empty list *)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-23&quot;&gt;&lt;a href=&quot;#cb3-23&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;val&lt;/span&gt; nil     :  &lt;span class=&quot;dt&quot;&gt;unit&lt;/span&gt; -&amp;gt; &amp;#39;a &lt;span class=&quot;dt&quot;&gt;list&lt;/span&gt; repr&lt;/span&gt;
&lt;span id=&quot;cb3-24&quot;&gt;&lt;a href=&quot;#cb3-24&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;co&quot;&gt;(* not empty *)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-25&quot;&gt;&lt;a href=&quot;#cb3-25&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;val&lt;/span&gt; exists  :  &amp;#39;a &lt;span class=&quot;dt&quot;&gt;list&lt;/span&gt; repr -&amp;gt;  &lt;span class=&quot;dt&quot;&gt;bool&lt;/span&gt; repr&lt;/span&gt;
&lt;span id=&quot;cb3-26&quot;&gt;&lt;a href=&quot;#cb3-26&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;co&quot;&gt;(* union list *)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-27&quot;&gt;&lt;a href=&quot;#cb3-27&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;val&lt;/span&gt; (@%)    : &amp;#39;a &lt;span class=&quot;dt&quot;&gt;list&lt;/span&gt; repr -&amp;gt; &amp;#39;a &lt;span class=&quot;dt&quot;&gt;list&lt;/span&gt; repr -&amp;gt; &amp;#39;a &lt;span class=&quot;dt&quot;&gt;list&lt;/span&gt; repr&lt;/span&gt;
&lt;span id=&quot;cb3-28&quot;&gt;&lt;a href=&quot;#cb3-28&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-29&quot;&gt;&lt;a href=&quot;#cb3-29&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;co&quot;&gt;(* the table constructor which take a table name and table contents *)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-30&quot;&gt;&lt;a href=&quot;#cb3-30&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;val&lt;/span&gt; table : (&lt;span class=&quot;dt&quot;&gt;string&lt;/span&gt; * &amp;#39;a &lt;span class=&quot;dt&quot;&gt;list&lt;/span&gt;) -&amp;gt; &amp;#39;a &lt;span class=&quot;dt&quot;&gt;list&lt;/span&gt; repr&lt;/span&gt;
&lt;span id=&quot;cb3-31&quot;&gt;&lt;a href=&quot;#cb3-31&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;(‘Symantics’ is not a typo; it’s a portmanteau of ‘syntax’ and
‘semantics’.)&lt;/p&gt;
&lt;h2 id=&quot;transformations&quot;&gt;Transformations&lt;/h2&gt;
&lt;p&gt;A SQL trasnformation (such as transforming a subquery to a join) is
represented by an ML functor, i.e. a function mapping one
&lt;code&gt;SymanticsL&lt;/code&gt; to another, which interprets the term slightly
differently than the original one. I say &lt;em&gt;slightly&lt;/em&gt;, because
normally a transformation touches only a few relevant methods. The
others are transformed mechanically following the &lt;a
href=&quot;http://okmij.org/ftp/tagless-final/course/rr.ml&quot;&gt;Reflection-Reification
pattern (RR)&lt;/a&gt;. Informally speaking, we leave the irrelevant methods
unchanged, applying the minimal transformation that makes them
typecheck.&lt;/p&gt;
&lt;p&gt;The question is, &lt;strong&gt;how to avoid mentioning irrelevant methods
when defining a transformation&lt;/strong&gt;?&lt;/p&gt;
&lt;p&gt;This question is not idle. The language-integrated query code
contains about 40 methods and 13 transformations. Pause for a second and
imagine the amount of boilerplate that would have to be written if we
needed to define every single method for every transformation. As we
will see below, ML modules make this a non-issue. In Haskell, however,
it is an issue, exhibited in &lt;a
href=&quot;http://okmij.org/ftp/tagless-final/course/B2Neg.hs&quot;&gt;Oleg’s own
Haskell example&lt;/a&gt; (although easy to miss for a class that only
contains 3 methods).&lt;/p&gt;
&lt;p&gt;In OCaml, the RR is defined as a transformation of the whole
module:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb4&quot;&gt;&lt;pre
class=&quot;sourceCode ocaml&quot;&gt;&lt;code class=&quot;sourceCode ocaml&quot;&gt;&lt;span id=&quot;cb4-1&quot;&gt;&lt;a href=&quot;#cb4-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;module&lt;/span&gt; OL(X:Trans)&lt;/span&gt;
&lt;span id=&quot;cb4-2&quot;&gt;&lt;a href=&quot;#cb4-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;         (F:SymanticsL &lt;span class=&quot;kw&quot;&gt;with&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;type&lt;/span&gt; &amp;#39;a repr = &amp;#39;a X.from)  = &lt;span class=&quot;kw&quot;&gt;struct&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-3&quot;&gt;&lt;a href=&quot;#cb4-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;include&lt;/span&gt; O(X)(F)&lt;/span&gt;
&lt;span id=&quot;cb4-4&quot;&gt;&lt;a href=&quot;#cb4-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;open&lt;/span&gt; X&lt;/span&gt;
&lt;span id=&quot;cb4-5&quot;&gt;&lt;a href=&quot;#cb4-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-6&quot;&gt;&lt;a href=&quot;#cb4-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;let&lt;/span&gt; foreach src body =&lt;/span&gt;
&lt;span id=&quot;cb4-7&quot;&gt;&lt;a href=&quot;#cb4-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    fwd (F.foreach (&lt;span class=&quot;kw&quot;&gt;fun&lt;/span&gt; () -&amp;gt; bwd (src ())) (&lt;span class=&quot;kw&quot;&gt;fun&lt;/span&gt; x -&amp;gt; bwd (body (fwd x))))&lt;/span&gt;
&lt;span id=&quot;cb4-8&quot;&gt;&lt;a href=&quot;#cb4-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;let&lt;/span&gt; where test body  =&lt;/span&gt;
&lt;span id=&quot;cb4-9&quot;&gt;&lt;a href=&quot;#cb4-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    fwd (F.where (bwd test) (&lt;span class=&quot;kw&quot;&gt;fun&lt;/span&gt; () -&amp;gt; bwd (body ())))&lt;/span&gt;
&lt;span id=&quot;cb4-10&quot;&gt;&lt;a href=&quot;#cb4-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;let&lt;/span&gt; yield e    = fmap F.yield e&lt;/span&gt;
&lt;span id=&quot;cb4-11&quot;&gt;&lt;a href=&quot;#cb4-11&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;let&lt;/span&gt; nil ()     = fwd (F.nil ())&lt;/span&gt;
&lt;span id=&quot;cb4-12&quot;&gt;&lt;a href=&quot;#cb4-12&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;let&lt;/span&gt; exists e   = fmap F.exists e&lt;/span&gt;
&lt;span id=&quot;cb4-13&quot;&gt;&lt;a href=&quot;#cb4-13&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;let&lt;/span&gt; (@%) e1 e2 = fmap2 F.(@%) e1 e2&lt;/span&gt;
&lt;span id=&quot;cb4-14&quot;&gt;&lt;a href=&quot;#cb4-14&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-15&quot;&gt;&lt;a href=&quot;#cb4-15&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;let&lt;/span&gt; table (name,data) =&lt;/span&gt;
&lt;span id=&quot;cb4-16&quot;&gt;&lt;a href=&quot;#cb4-16&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    fwd @@ F.table (name, data)&lt;/span&gt;
&lt;span id=&quot;cb4-17&quot;&gt;&lt;a href=&quot;#cb4-17&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;When they define a transformation, they first transform the module in
this mechanical fashion, and then override the few relevant methods:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb5&quot;&gt;&lt;pre
class=&quot;sourceCode ocaml&quot;&gt;&lt;code class=&quot;sourceCode ocaml&quot;&gt;&lt;span id=&quot;cb5-1&quot;&gt;&lt;a href=&quot;#cb5-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;module&lt;/span&gt; AbsBeta_pass(F:SymanticsL) = &lt;span class=&quot;kw&quot;&gt;struct&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-2&quot;&gt;&lt;a href=&quot;#cb5-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;module&lt;/span&gt; X0 = &lt;span class=&quot;kw&quot;&gt;struct&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-3&quot;&gt;&lt;a href=&quot;#cb5-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;kw&quot;&gt;type&lt;/span&gt; &amp;#39;a from = &amp;#39;a F.repr&lt;/span&gt;
&lt;span id=&quot;cb5-4&quot;&gt;&lt;a href=&quot;#cb5-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;kw&quot;&gt;type&lt;/span&gt; &amp;#39;a term = Unknown : &amp;#39;a from -&amp;gt; &amp;#39;a term&lt;/span&gt;
&lt;span id=&quot;cb5-5&quot;&gt;&lt;a href=&quot;#cb5-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;             | Lam     : (&amp;#39;a term -&amp;gt; &amp;#39;b term) -&amp;gt; (&amp;#39;a -&amp;gt; &amp;#39;b) term&lt;/span&gt;
&lt;span id=&quot;cb5-6&quot;&gt;&lt;a href=&quot;#cb5-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;kw&quot;&gt;let&lt;/span&gt; fwd x = Unknown x                              &lt;span class=&quot;co&quot;&gt;(* generic reflection *)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-7&quot;&gt;&lt;a href=&quot;#cb5-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;kw&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;rec&lt;/span&gt; bwd : &lt;span class=&quot;kw&quot;&gt;type&lt;/span&gt; a. a term -&amp;gt; a from = &lt;span class=&quot;kw&quot;&gt;function&lt;/span&gt;  &lt;span class=&quot;co&quot;&gt;(* reification *)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-8&quot;&gt;&lt;a href=&quot;#cb5-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      | Unknown e -&amp;gt; e&lt;/span&gt;
&lt;span id=&quot;cb5-9&quot;&gt;&lt;a href=&quot;#cb5-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      | Lam f     -&amp;gt; F.lam (&lt;span class=&quot;kw&quot;&gt;fun&lt;/span&gt; x -&amp;gt; bwd (f (fwd x)))&lt;/span&gt;
&lt;span id=&quot;cb5-10&quot;&gt;&lt;a href=&quot;#cb5-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;end&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-11&quot;&gt;&lt;a href=&quot;#cb5-11&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;open&lt;/span&gt; X0&lt;/span&gt;
&lt;span id=&quot;cb5-12&quot;&gt;&lt;a href=&quot;#cb5-12&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;module&lt;/span&gt; X = Trans_def(X0)&lt;/span&gt;
&lt;span id=&quot;cb5-13&quot;&gt;&lt;a href=&quot;#cb5-13&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;open&lt;/span&gt; X&lt;/span&gt;
&lt;span id=&quot;cb5-14&quot;&gt;&lt;a href=&quot;#cb5-14&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;co&quot;&gt;(* optimization *)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-15&quot;&gt;&lt;a href=&quot;#cb5-15&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;module&lt;/span&gt; IDelta = &lt;span class=&quot;kw&quot;&gt;struct&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-16&quot;&gt;&lt;a href=&quot;#cb5-16&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;kw&quot;&gt;let&lt;/span&gt; lam f = Lam f&lt;/span&gt;
&lt;span id=&quot;cb5-17&quot;&gt;&lt;a href=&quot;#cb5-17&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;kw&quot;&gt;let&lt;/span&gt; app e1 e2 =&lt;/span&gt;
&lt;span id=&quot;cb5-18&quot;&gt;&lt;a href=&quot;#cb5-18&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;kw&quot;&gt;match&lt;/span&gt; e1 &lt;span class=&quot;kw&quot;&gt;with&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-19&quot;&gt;&lt;a href=&quot;#cb5-19&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      | Lam f -&amp;gt; f e2&lt;/span&gt;
&lt;span id=&quot;cb5-20&quot;&gt;&lt;a href=&quot;#cb5-20&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      | _ -&amp;gt; fmap2 F.app e1 e2&lt;/span&gt;
&lt;span id=&quot;cb5-21&quot;&gt;&lt;a href=&quot;#cb5-21&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;end&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-22&quot;&gt;&lt;a href=&quot;#cb5-22&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;end&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-23&quot;&gt;&lt;a href=&quot;#cb5-23&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-24&quot;&gt;&lt;a href=&quot;#cb5-24&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;co&quot;&gt;(* Combine the concrete optimization with the default optimizer *)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-25&quot;&gt;&lt;a href=&quot;#cb5-25&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;module&lt;/span&gt; AbsBeta(F:SymanticsL) = &lt;span class=&quot;kw&quot;&gt;struct&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-26&quot;&gt;&lt;a href=&quot;#cb5-26&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;module&lt;/span&gt; M = AbsBeta_pass(F)&lt;/span&gt;
&lt;span id=&quot;cb5-27&quot;&gt;&lt;a href=&quot;#cb5-27&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;include&lt;/span&gt; OL(M.X)(F)        &lt;span class=&quot;co&quot;&gt;(* the default optimizer *)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-28&quot;&gt;&lt;a href=&quot;#cb5-28&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;include&lt;/span&gt; M.IDelta          &lt;span class=&quot;co&quot;&gt;(* overriding `lam` and `app` *)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-29&quot;&gt;&lt;a href=&quot;#cb5-29&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;How can we do this in Haskell?&lt;/p&gt;
&lt;h2 id=&quot;explicit-dictionaries&quot;&gt;Explicit dictionaries&lt;/h2&gt;
&lt;p&gt;An explicit dictionariy (a data type containing methods as its
fields) seems like a great fit for &lt;code&gt;Symantics&lt;/code&gt;. The RR
transformation would be a simple function mapping one record to another.
To define a transformation, we would override the relevant methods via
record update.&lt;/p&gt;
&lt;p&gt;However, explicit dictionaries are not that well suited for the
finally tagless style. In OCaml, you can include one module into another
(notice &lt;code&gt;include Symantics&lt;/code&gt; in the OCaml code above). This
“unpacks” the contents of one module into another, so that when you open
the second module, the contents of the first module is available,
too.&lt;/p&gt;
&lt;p&gt;This is important for the finally tagless style. One of its strength
is extensibility, which is achieved through such inclusion.
Consequently, deep inclusion chains are common. With Haskell’s data
types, unpacking such chains manually at every use site will quickly
become unwieldy.&lt;/p&gt;
&lt;h2 id=&quot;type-classes&quot;&gt;Type classes&lt;/h2&gt;
&lt;p&gt;Type classes are better suited for inclusion. If we declare&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb6&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb6-1&quot;&gt;&lt;a href=&quot;#cb6-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Symantics1&lt;/span&gt; rep &lt;span class=&quot;ot&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Symantics2&lt;/span&gt; rep &lt;span class=&quot;kw&quot;&gt;where&lt;/span&gt; { &lt;span class=&quot;op&quot;&gt;...&lt;/span&gt; }&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;and impose a &lt;code&gt;Symantics2 rep&lt;/code&gt; constraint on a function
definition, the methods of &lt;code&gt;Symantics1&lt;/code&gt; become available
without any additional effort.&lt;/p&gt;
&lt;p&gt;But then we don’t have good support for RR. Type class instances are
not first class citizens; we can’t declare a function that transforms
one instance into another. Nor can we create one instance from another
by overriding a few methods… Or can we?&lt;/p&gt;
&lt;p&gt;We can achieve our goal by using &lt;a
href=&quot;https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/type-class-extensions.html#class-default-signatures&quot;&gt;default
method signatures&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;We define the RR transformation simultaneously with the class
itself:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb7&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb7-1&quot;&gt;&lt;a href=&quot;#cb7-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Symantics&lt;/span&gt; rep &lt;span class=&quot;kw&quot;&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb7-2&quot;&gt;&lt;a href=&quot;#cb7-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;  lam ::&lt;/span&gt; (rep a &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; rep b) &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; rep (a &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; b)&lt;/span&gt;
&lt;span id=&quot;cb7-3&quot;&gt;&lt;a href=&quot;#cb7-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  default&lt;span class=&quot;ot&quot;&gt; lam ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;RR&lt;/span&gt; t rep &lt;span class=&quot;ot&quot;&gt;=&amp;gt;&lt;/span&gt; (t rep a &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; t rep b) &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; t rep (a &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; b)&lt;/span&gt;
&lt;span id=&quot;cb7-4&quot;&gt;&lt;a href=&quot;#cb7-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  lam f &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; fwd &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; lam &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; bwd &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt; f &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt; fwd&lt;/span&gt;
&lt;span id=&quot;cb7-5&quot;&gt;&lt;a href=&quot;#cb7-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb7-6&quot;&gt;&lt;a href=&quot;#cb7-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;  app ::&lt;/span&gt; rep (a &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; b) &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; rep a &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; rep b&lt;/span&gt;
&lt;span id=&quot;cb7-7&quot;&gt;&lt;a href=&quot;#cb7-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  default&lt;span class=&quot;ot&quot;&gt; app ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;RR&lt;/span&gt; t rep &lt;span class=&quot;ot&quot;&gt;=&amp;gt;&lt;/span&gt; t rep (a &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; b) &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; t rep a &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; t rep b&lt;/span&gt;
&lt;span id=&quot;cb7-8&quot;&gt;&lt;a href=&quot;#cb7-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  app f x &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; fwd &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; bwd f &lt;span class=&quot;ot&quot;&gt;`app`&lt;/span&gt; bwd x&lt;/span&gt;
&lt;span id=&quot;cb7-9&quot;&gt;&lt;a href=&quot;#cb7-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb7-10&quot;&gt;&lt;a href=&quot;#cb7-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;  foreach ::&lt;/span&gt; rep [a] &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; (rep a &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; rep [b]) &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; rep [b]&lt;/span&gt;
&lt;span id=&quot;cb7-11&quot;&gt;&lt;a href=&quot;#cb7-11&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  default&lt;span class=&quot;ot&quot;&gt; foreach ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;RR&lt;/span&gt; t rep &lt;span class=&quot;ot&quot;&gt;=&amp;gt;&lt;/span&gt; t rep [a] &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; (t rep a &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; t rep [b]) &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; t rep [b]&lt;/span&gt;
&lt;span id=&quot;cb7-12&quot;&gt;&lt;a href=&quot;#cb7-12&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  foreach a b &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; fwd &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; foreach (bwd a) (bwd &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt; b &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt; fwd)&lt;/span&gt;
&lt;span id=&quot;cb7-13&quot;&gt;&lt;a href=&quot;#cb7-13&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb7-14&quot;&gt;&lt;a href=&quot;#cb7-14&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;op&quot;&gt;...&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The implementation of &lt;code&gt;RR&lt;/code&gt; is straightforward:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb8&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb8-1&quot;&gt;&lt;a href=&quot;#cb8-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;RR&lt;/span&gt; t rep &lt;span class=&quot;kw&quot;&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb8-2&quot;&gt;&lt;a href=&quot;#cb8-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;  fwd ::&lt;/span&gt; rep a &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; t rep a&lt;/span&gt;
&lt;span id=&quot;cb8-3&quot;&gt;&lt;a href=&quot;#cb8-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;  bwd ::&lt;/span&gt; t rep a &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; rep a&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now let’s define the AbsBeta pass in Haskell.&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb9&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb9-1&quot;&gt;&lt;a href=&quot;#cb9-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;AbsBeta&lt;/span&gt; rep a &lt;span class=&quot;kw&quot;&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb9-2&quot;&gt;&lt;a href=&quot;#cb9-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;dt&quot;&gt;Unknown&lt;/span&gt;&lt;span class=&quot;ot&quot;&gt; ::&lt;/span&gt; rep a &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;AbsBeta&lt;/span&gt; rep a&lt;/span&gt;
&lt;span id=&quot;cb9-3&quot;&gt;&lt;a href=&quot;#cb9-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;dt&quot;&gt;Lam&lt;/span&gt;&lt;span class=&quot;ot&quot;&gt; ::&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;AbsBeta&lt;/span&gt; rep a &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;AbsBeta&lt;/span&gt; rep b) &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;AbsBeta&lt;/span&gt; rep (a &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; b)&lt;/span&gt;
&lt;span id=&quot;cb9-4&quot;&gt;&lt;a href=&quot;#cb9-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb9-5&quot;&gt;&lt;a href=&quot;#cb9-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;instance&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Symantics&lt;/span&gt; rep &lt;span class=&quot;ot&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;RR&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;AbsBeta&lt;/span&gt; rep &lt;span class=&quot;kw&quot;&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb9-6&quot;&gt;&lt;a href=&quot;#cb9-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  fwd &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Unknown&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb9-7&quot;&gt;&lt;a href=&quot;#cb9-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  bwd &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; \&lt;span class=&quot;kw&quot;&gt;case&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb9-8&quot;&gt;&lt;a href=&quot;#cb9-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;dt&quot;&gt;Unknown&lt;/span&gt; t &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; t&lt;/span&gt;
&lt;span id=&quot;cb9-9&quot;&gt;&lt;a href=&quot;#cb9-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;dt&quot;&gt;Lam&lt;/span&gt; f &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; lam (bwd &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt; f &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt; fwd)&lt;/span&gt;
&lt;span id=&quot;cb9-10&quot;&gt;&lt;a href=&quot;#cb9-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb9-11&quot;&gt;&lt;a href=&quot;#cb9-11&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;instance&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Symantics&lt;/span&gt; rep &lt;span class=&quot;ot&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Symantics&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;AbsBeta&lt;/span&gt; rep) &lt;span class=&quot;kw&quot;&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb9-12&quot;&gt;&lt;a href=&quot;#cb9-12&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  lam &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Lam&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb9-13&quot;&gt;&lt;a href=&quot;#cb9-13&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  app f x &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb9-14&quot;&gt;&lt;a href=&quot;#cb9-14&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;kw&quot;&gt;case&lt;/span&gt; f &lt;span class=&quot;kw&quot;&gt;of&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb9-15&quot;&gt;&lt;a href=&quot;#cb9-15&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;dt&quot;&gt;Unknown&lt;/span&gt; f&amp;#39; &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; fwd &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; app f&amp;#39; (bwd x)&lt;/span&gt;
&lt;span id=&quot;cb9-16&quot;&gt;&lt;a href=&quot;#cb9-16&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;dt&quot;&gt;Lam&lt;/span&gt; b &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; b x&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;All the methods not mentioned in the last instance get their default
implementations based on RR, which is exactly what we wanted.&lt;/p&gt;
&lt;h2 id=&quot;associated-types&quot;&gt;Associated types&lt;/h2&gt;
&lt;p&gt;Apart from methods, ML/OCaml modules can also define types. This is
used in the Language-integrated query paper and code in the following
way:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb10&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb10-1&quot;&gt;&lt;a href=&quot;#cb10-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;(&lt;span class=&quot;op&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Base&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Symantics&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;*&lt;/span&gt;)&lt;/span&gt;
&lt;span id=&quot;cb10-2&quot;&gt;&lt;a href=&quot;#cb10-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;module&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Symantics_base&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; sig&lt;/span&gt;
&lt;span id=&quot;cb10-3&quot;&gt;&lt;a href=&quot;#cb10-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;type&lt;/span&gt; &amp;#39;a repr  (&lt;span class=&quot;op&quot;&gt;*&lt;/span&gt; representation &lt;span class=&quot;kw&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;*&lt;/span&gt;)&lt;/span&gt;
&lt;span id=&quot;cb10-4&quot;&gt;&lt;a href=&quot;#cb10-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  val observe &lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; (unit &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &amp;#39;a repr) &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &amp;#39;a obs&lt;/span&gt;
&lt;span id=&quot;cb10-5&quot;&gt;&lt;a href=&quot;#cb10-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;op&quot;&gt;...&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;In Haskell, we can replicate that with an associated type:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb11&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb11-1&quot;&gt;&lt;a href=&quot;#cb11-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;SymanticsObs&lt;/span&gt; rep &lt;span class=&quot;kw&quot;&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb11-2&quot;&gt;&lt;a href=&quot;#cb11-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Obs&lt;/span&gt;&lt;span class=&quot;ot&quot;&gt; rep ::&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;*&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb11-3&quot;&gt;&lt;a href=&quot;#cb11-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb11-4&quot;&gt;&lt;a href=&quot;#cb11-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;  observe ::&lt;/span&gt; rep a &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Obs&lt;/span&gt; rep a&lt;/span&gt;
&lt;span id=&quot;cb11-5&quot;&gt;&lt;a href=&quot;#cb11-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  default&lt;span class=&quot;ot&quot;&gt; observe ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;RR&lt;/span&gt; t rep &lt;span class=&quot;ot&quot;&gt;=&amp;gt;&lt;/span&gt; t rep a &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Obs&lt;/span&gt; rep a&lt;/span&gt;
&lt;span id=&quot;cb11-6&quot;&gt;&lt;a href=&quot;#cb11-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  observe &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; observe &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt; bwd&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The default definition for &lt;code&gt;observe&lt;/code&gt; saves us from
redefining it for derived representations, but what about
&lt;code&gt;Obs&lt;/code&gt; itself? We would like to write, in the spirit of
default method signatures,&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb12&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb12-1&quot;&gt;&lt;a href=&quot;#cb12-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;SymanticsObs&lt;/span&gt; rep &lt;span class=&quot;kw&quot;&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb12-2&quot;&gt;&lt;a href=&quot;#cb12-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Obs&lt;/span&gt;&lt;span class=&quot;ot&quot;&gt; rep ::&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;*&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb12-3&quot;&gt;&lt;a href=&quot;#cb12-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Obs&lt;/span&gt; (t rep) &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; rep&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;However, GHC would not let us to. Since recently, GHC does support
default type declarations, but they need to be of the general form
&lt;code&gt;type Obs rep = ...&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Nevertheless, we can create a type family that will extract the
&lt;code&gt;rep&lt;/code&gt; from &lt;code&gt;t rep&lt;/code&gt; for us:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb13&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb13-1&quot;&gt;&lt;a href=&quot;#cb13-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;family&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Peel&lt;/span&gt; (&lt;span class=&quot;ot&quot;&gt;rep ::&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;*&lt;/span&gt;)&lt;span class=&quot;ot&quot;&gt; ::&lt;/span&gt; (&lt;span class=&quot;op&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;*&lt;/span&gt;) &lt;span class=&quot;kw&quot;&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb13-2&quot;&gt;&lt;a href=&quot;#cb13-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;dt&quot;&gt;Peel&lt;/span&gt; (t rep) &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; rep&lt;/span&gt;
&lt;span id=&quot;cb13-3&quot;&gt;&lt;a href=&quot;#cb13-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb13-4&quot;&gt;&lt;a href=&quot;#cb13-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;SymanticsObs&lt;/span&gt; rep &lt;span class=&quot;kw&quot;&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb13-5&quot;&gt;&lt;a href=&quot;#cb13-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Obs&lt;/span&gt;&lt;span class=&quot;ot&quot;&gt; rep ::&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;*&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb13-6&quot;&gt;&lt;a href=&quot;#cb13-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Obs&lt;/span&gt; rep &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Obs&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;Peel&lt;/span&gt; rep)&lt;/span&gt;
&lt;span id=&quot;cb13-7&quot;&gt;&lt;a href=&quot;#cb13-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb13-8&quot;&gt;&lt;a href=&quot;#cb13-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;  observe ::&lt;/span&gt; rep a &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Obs&lt;/span&gt; rep a&lt;/span&gt;
&lt;span id=&quot;cb13-9&quot;&gt;&lt;a href=&quot;#cb13-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  default&lt;span class=&quot;ot&quot;&gt; observe ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;RR&lt;/span&gt; t rep &lt;span class=&quot;ot&quot;&gt;=&amp;gt;&lt;/span&gt; t rep a &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Obs&lt;/span&gt; rep a&lt;/span&gt;
&lt;span id=&quot;cb13-10&quot;&gt;&lt;a href=&quot;#cb13-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  observe &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; observe &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt; bwd&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now we can say&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb14&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb14-1&quot;&gt;&lt;a href=&quot;#cb14-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;instance&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;Symantics&lt;/span&gt; rep, &lt;span class=&quot;dt&quot;&gt;SymanticsObs&lt;/span&gt; rep) &lt;span class=&quot;ot&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;SymanticsObs&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;AbsBeta&lt;/span&gt; rep)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;without having to define either &lt;code&gt;type Obs&lt;/code&gt; or
&lt;code&gt;observe&lt;/code&gt; explicitly.&lt;/p&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Extensions such as default method signatures, default associated
types, and type families can significantly reduce the boilerplate when
defining transformations in the finally tagless style.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Update.&lt;/em&gt; Although I missed it on the first reading of the &lt;a
href=&quot;http://okmij.org/ftp/meta-programming/quel.pdf&quot;&gt;paper&lt;/a&gt;, &lt;a
href=&quot;https://www.reddit.com/user/rpglover64&quot;&gt;/u/rpglover64&lt;/a&gt; on
reddit &lt;a
href=&quot;https://www.reddit.com/r/haskell/comments/4416gn/reducing_boilerplate_in_finally_tagless_style/czmre14&quot;&gt;points
out&lt;/a&gt; that the authors themselves acknowledge the boilerplate problem
which this article addresses:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Haskell typeclasses made the encoding lightweight compared to OCaml
modules. On the other hand, in OCaml we relied on the include mechanism
to program optimizations by reusing the code for the identity
transformation and overriding a couple of definitions. Haskell does not
support that sort of code reuse among type classes. Therefore,
programming tagless-final transformation in Haskell has quite a bit of
boilerplate.&lt;/p&gt;
&lt;/blockquote&gt;
</description>
                        <pubDate>Wed, 03 Feb 2016 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2016-02-03-finally-tagless-boilerplate</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2016-02-03-finally-tagless-boilerplate.html</guid>
                </item>
        
                <item>
                        <title>Fixing Permission denied (publickey). after an SSH upgrade</title>
                        <description>&lt;p&gt;This weekend I upgraded my laptop from Fedora 22 to 23. Today, when I
tried to push to github, I suddenly got&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% git push     
Permission denied (publickey).
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To debug this, I ran (according to &lt;a
href=&quot;https://help.github.com/articles/error-permission-denied-publickey/&quot;&gt;these
instructions&lt;/a&gt;)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% ssh -vT git@github.com
OpenSSH_7.1p1, OpenSSL 1.0.2e-fips 3 Dec 2015
debug1: Reading configuration data /home/feuerbach/.ssh/config
debug1: Reading configuration data /etc/ssh/ssh_config
debug1: /etc/ssh/ssh_config line 56: Applying options for *
debug1: Connecting to github.com [192.30.252.129] port 22.
debug1: Connection established.
debug1: identity file /home/feuerbach/.ssh/id_rsa type 1
debug1: key_load_public: No such file or directory
debug1: identity file /home/feuerbach/.ssh/id_rsa-cert type -1
debug1: identity file /home/feuerbach/.ssh/id_dsa type 2
debug1: key_load_public: No such file or directory
debug1: identity file /home/feuerbach/.ssh/id_dsa-cert type -1
debug1: key_load_public: No such file or directory
debug1: identity file /home/feuerbach/.ssh/id_ecdsa type -1
debug1: key_load_public: No such file or directory
debug1: identity file /home/feuerbach/.ssh/id_ecdsa-cert type -1
debug1: key_load_public: No such file or directory
debug1: identity file /home/feuerbach/.ssh/id_ed25519 type -1
debug1: key_load_public: No such file or directory
debug1: identity file /home/feuerbach/.ssh/id_ed25519-cert type -1
debug1: Enabling compatibility mode for protocol 2.0
debug1: Local version string SSH-2.0-OpenSSH_7.1
debug1: Remote protocol version 2.0, remote software version libssh-0.7.0
debug1: no match: libssh-0.7.0
debug1: Authenticating to github.com:22 as &amp;#39;git&amp;#39;
debug1: SSH2_MSG_KEXINIT sent
debug1: SSH2_MSG_KEXINIT received
debug1: kex: server-&amp;gt;client chacha20-poly1305@openssh.com &amp;lt;implicit&amp;gt; none
debug1: kex: client-&amp;gt;server chacha20-poly1305@openssh.com &amp;lt;implicit&amp;gt; none
debug1: kex: curve25519-sha256@libssh.org need=64 dh_need=64
debug1: kex: curve25519-sha256@libssh.org need=64 dh_need=64
debug1: expecting SSH2_MSG_KEX_ECDH_REPLY
debug1: Server host key: ssh-rsa SHA256:nThbg6kXUpJWGl7E1IGOCspRomTxdCARLviKw6E5SY8
debug1: Host &amp;#39;github.com&amp;#39; is known and matches the RSA host key.
debug1: Found key in /home/feuerbach/.ssh/known_hosts:19
debug1: SSH2_MSG_NEWKEYS sent
debug1: expecting SSH2_MSG_NEWKEYS
debug1: SSH2_MSG_NEWKEYS received
debug1: Roaming not allowed by server
debug1: SSH2_MSG_SERVICE_REQUEST sent
debug1: SSH2_MSG_SERVICE_ACCEPT received
debug1: Authentications that can continue: publickey
debug1: Next authentication method: publickey
debug1: Offering RSA public key: /home/feuerbach/.ssh/id_rsa
debug1: Authentications that can continue: publickey
debug1: Skipping ssh-dss key /home/feuerbach/.ssh/id_dsa for not in PubkeyAcceptedKeyTypes
debug1: Trying private key: /home/feuerbach/.ssh/id_ecdsa
debug1: Trying private key: /home/feuerbach/.ssh/id_ed25519
debug1: No more authentication methods to try.
Permission denied (publickey).&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The important line is this one&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;debug1: Skipping ssh-dss key /home/feuerbach/.ssh/id_dsa for not in PubkeyAcceptedKeyTypes&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It turns out that Fedora 23 ships with OpenSSH 7.1p1 which has &lt;a
href=&quot;https://www.gentoo.org/support/news-items/2015-08-13-openssh-weak-keys.html&quot;&gt;disabled&lt;/a&gt;
DSS (&lt;a href=&quot;http://security.stackexchange.com/q/51567/29041&quot;&gt;aka
DSA&lt;/a&gt;) keys by default.&lt;/p&gt;
&lt;p&gt;A short term solution is to add&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Host *
PubkeyAcceptedKeyTypes=+ssh-dss&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;to &lt;code&gt;~/.ssh/config&lt;/code&gt;. A long-term solution is to replace the
DSS keys with, say, RSA keys.&lt;/p&gt;
</description>
                        <pubDate>Mon, 21 Dec 2015 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2015-12-21-permission-denied-publickey-ssh-update</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2015-12-21-permission-denied-publickey-ssh-update.html</guid>
                </item>
        
                <item>
                        <title>Torsors, midpoints, and homogeneous coordinates</title>
                        <description>&lt;p&gt;Gustavo Goretkin writes:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Dear Roman,&lt;/p&gt;
&lt;p&gt;I’ve thought about torsors for a while but only came across &lt;a
href=&quot;2013-01-08-torsors&quot;&gt;your page&lt;/a&gt; on it today.&lt;/p&gt;
&lt;p&gt;Regarding the distinction between Vectors and Points, I think it’s
useful to have this distinction in programming languages. Graphics
people sometimes do this when they use normalized homogeneous
coordinates. A point &lt;span class=&quot;math inline&quot;&gt;\(P(x,y,z)\)&lt;/span&gt; is
represented as &lt;span class=&quot;math inline&quot;&gt;\([x,y,z,1]\)&lt;/span&gt; and a
vector &lt;span class=&quot;math inline&quot;&gt;\(V(x,y,z)\)&lt;/span&gt; is represented as
&lt;span class=&quot;math inline&quot;&gt;\([x,y,z,0]\)&lt;/span&gt;. If you add a &lt;span
class=&quot;math inline&quot;&gt;\(V+V\)&lt;/span&gt;, you get a &lt;span
class=&quot;math inline&quot;&gt;\(V\)&lt;/span&gt;, if you add &lt;span
class=&quot;math inline&quot;&gt;\(P+V\)&lt;/span&gt;, you get a &lt;span
class=&quot;math inline&quot;&gt;\(P\)&lt;/span&gt;. If you do &lt;span
class=&quot;math inline&quot;&gt;\(P-P\)&lt;/span&gt;, you get a &lt;span
class=&quot;math inline&quot;&gt;\(V\)&lt;/span&gt;. Finally, If you add &lt;span
class=&quot;math inline&quot;&gt;\(P+P\)&lt;/span&gt;, you get a homogeneous coordinate
with last coordinate 2.&lt;/p&gt;
&lt;p&gt;Now, I don’t know how to attach a geometric meaning to the point
&lt;span class=&quot;math inline&quot;&gt;\(P_1+P_2\)&lt;/span&gt;, however, I think it is
convenient to allow the average of &lt;span
class=&quot;math inline&quot;&gt;\(P_1\)&lt;/span&gt; and &lt;span
class=&quot;math inline&quot;&gt;\(P_2\)&lt;/span&gt; to be the point in between &lt;span
class=&quot;math inline&quot;&gt;\(P_1\)&lt;/span&gt; and &lt;span
class=&quot;math inline&quot;&gt;\(P_2\)&lt;/span&gt;—halfway along the geodesic connecting
the two points. Which is what happens if you normalize the homogeneous
point above, because you divide all coordinates by two.&lt;/p&gt;
&lt;p&gt;If I were using a programming language that did not allow me to add
two points, I know what I’d do. I’d choose an arbitrary point &lt;span
class=&quot;math inline&quot;&gt;\(c\)&lt;/span&gt; and perform&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;math display&quot;&gt;\[\frac{(P_1-c) + (P_2-c)}2 +
c.\]&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;This feels like a dilemma, though, because this produces the
identical result as if you had allowed &lt;span
class=&quot;math inline&quot;&gt;\(\frac{P_1+P_2}2\)&lt;/span&gt;. Perhaps my dilemma is
purely rooted in pragmatics, but I wanted to know if you had any
thoughts.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;is-this-even-legal&quot;&gt;Is this even legal?&lt;/h2&gt;
&lt;p&gt;So we have two ways to compute the midpoint of &lt;span
class=&quot;math inline&quot;&gt;\(P_1P_2\)&lt;/span&gt;. One is legal under the
points-as-a-torsor interpretation and does not involve point
addition:&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;math display&quot;&gt;\[\frac{(P_1-c) + (P_2-c)}2 +
c,\]&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;where &lt;span class=&quot;math inline&quot;&gt;\(c\)&lt;/span&gt; is arbitrary. A simpler
(and still legal) formula is obtained by letting &lt;span
class=&quot;math inline&quot;&gt;\(c=P_1\)&lt;/span&gt;:&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;math display&quot;&gt;\[\frac{P_2-P_1}2 + P_1.\]&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;On the other hand, we have a formula that “just works” if we allow
point addition:&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;math display&quot;&gt;\[\frac{P_1+P_2}2.\]&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Should the existence of this latter formula cast a shadow of doubt on
the first two and the concept of a midpoint? Certainly not!&lt;/p&gt;
&lt;p&gt;Why does the illegal formula work? Any torsor can be transformed into
a proper linear space by choosing an arbtrary element of the torsor,
&lt;span class=&quot;math inline&quot;&gt;\(c\)&lt;/span&gt;, and designating it as zero. Then
we can compute any linear combination &lt;span class=&quot;math inline&quot;&gt;\(\alpha
P_1+\beta P_2\)&lt;/span&gt; just as we computed the midpoint above, &lt;span
class=&quot;math inline&quot;&gt;\(\alpha(P_1-c) + \beta(P_2 - c) + c.\)&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;The problem with this approach, in general, is that the result will
vary with the choice of &lt;span class=&quot;math inline&quot;&gt;\(c\)&lt;/span&gt;.
Indeed,&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;math display&quot;&gt;\[
(\alpha(P_1-c_1) + \beta(P_2 - c_1) + c_1) - \\
(\alpha(P_1-c_2) + \beta(P_2 - c_2) + c_2) = \\
(\alpha+\beta-1)(c_2-c_1)
\]&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Thus, the result will be independent of &lt;span
class=&quot;math inline&quot;&gt;\(c\)&lt;/span&gt; only in the case &lt;span
class=&quot;math inline&quot;&gt;\(\alpha+\beta=1\)&lt;/span&gt;, that is, when the linear
combination is &lt;a
href=&quot;https://en.wikipedia.org/wiki/Affine_combination&quot;&gt;affine&lt;/a&gt;.
Luckily, computing the midpoint happens to be such a combination, with
&lt;span class=&quot;math inline&quot;&gt;\(\alpha=\beta=1/2\)&lt;/span&gt;.&lt;/p&gt;
&lt;h2 id=&quot;interface-vs.-implementation&quot;&gt;Interface vs. implementation&lt;/h2&gt;
&lt;p&gt;If we wish to design a safer language that does not let us
accidentally add points, we should not allow expressions like &lt;span
class=&quot;math inline&quot;&gt;\(\alpha P_1 + \beta P_2\)&lt;/span&gt;, unless we can
statically verify that &lt;span class=&quot;math inline&quot;&gt;\(\alpha + \beta =
1\)&lt;/span&gt;. But since, as we’ve established, an affine combination of
two (and, by extension, &lt;span class=&quot;math inline&quot;&gt;\(n\)&lt;/span&gt;) points
does make geometric sense, we would want to introduce a function like
the following:&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;math display&quot;&gt;\[
\mathrm{affine}(\alpha_1,P_1;\alpha_2,P_2;\ldots;\alpha_n,P_n) =
\frac{\alpha_1 P_1+\alpha_2 P_2+\ldots+\alpha_n P_n}{\alpha_1 +\alpha_2
+\ldots+\alpha_n}
\label{affine}
\]&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;The division by &lt;span class=&quot;math inline&quot;&gt;\(\sum \alpha_i\)&lt;/span&gt;
ensures that the combination is indeed affine and thus legal.&lt;/p&gt;
&lt;p&gt;Internally, the function may be computed by any of the formulae shown
above, even if some of them may be not allowed in the surface language.
Usually, the straightforward definition above will be the fastest. A &lt;a
href=&quot;https://en.wikipedia.org/wiki/Kahan_summation_algorithm&quot;&gt;smarter
algorithm&lt;/a&gt; could be employed to achieve better numeric stability. And
in rare cases such as dealing with bounded numbers, the formula &lt;span
class=&quot;math inline&quot;&gt;\(\frac{P_2-P_1}2 + P_1\)&lt;/span&gt; is required to &lt;a
href=&quot;http://googleresearch.blogspot.de/2006/06/extra-extra-read-all-about-it-nearly.html&quot;&gt;avoid
overflow&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;homogeneous-coordinates&quot;&gt;Homogeneous coordinates&lt;/h2&gt;
&lt;p&gt;It may seem as if our &lt;span
class=&quot;math inline&quot;&gt;\(\mathrm{affine}\)&lt;/span&gt; function is equivalent to
addition in homogeneous coordinates; but there is one important
distinction. Homogeneous coordinates are stateful; the sum &lt;span
class=&quot;math inline&quot;&gt;\(\sum\alpha_i\)&lt;/span&gt; is simply stored along the
vector &lt;span class=&quot;math inline&quot;&gt;\(\sum\alpha_iP_i\)&lt;/span&gt;, and the
division is implicit. Thus two geometrically identical points may behave
differently when added to a third point:&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;math display&quot;&gt;\[
[6,6,6,1]    + [0,0,0,1] = [6,6,6,2] \sim (3,3,3) \\
[12,12,12,2] + [0,0,0,1] = [12,12,12,3] \sim (4,4,4)
\]&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Homogeneous coordinates are a very powerful concept, but as a
programming model they are error-prone. A safer model could be devised
if the language can statically distinguish (say, through types) between
points, vectors, and possibly denormalized points.&lt;/p&gt;
</description>
                        <pubDate>Wed, 16 Dec 2015 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2015-12-16-torsors-midpoints-homogeneous-coordinates</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2015-12-16-torsors-midpoints-homogeneous-coordinates.html</guid>
                </item>
        
                <item>
                        <title>Testing FFT with R</title>
                        <description>&lt;p&gt;In the &lt;a href=&quot;2015-12-04-fft&quot;&gt;previous article&lt;/a&gt;, we have built a
simple FFT algorithm in Haskell. Now it’s time to test it, for
correctness and for (asymptotic) efficiency. If you expect the
conclusion to be “it’s good” on both accounts, read on; it may get a bit
more interesting than that.&lt;/p&gt;
&lt;p&gt;This is also a good occasion to introduce and play with &lt;a
href=&quot;https://tweag.github.io/HaskellR/&quot;&gt;inline-r&lt;/a&gt;, a Haskell package
that allows to run R code from within Haskell.&lt;/p&gt;
&lt;h2 id=&quot;testing-correctness&quot;&gt;Testing correctness&lt;/h2&gt;
&lt;p&gt;In R, FFT is available straight out of the box, without a need to
import a single package.&lt;/p&gt;
&lt;p&gt;We use tasty and quickcheck to generate random lists of complex
numbers, run R’s FFT and our implementation on these random inputs and
compare the results.&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb1&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb1-1&quot;&gt;&lt;a href=&quot;#cb1-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;{-# LANGUAGE QuasiQuotes, ScopedTypeVariables, DataKinds, PartialTypeSignatures, GADTs #-}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-2&quot;&gt;&lt;a href=&quot;#cb1-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Test.Tasty&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-3&quot;&gt;&lt;a href=&quot;#cb1-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Test.Tasty.QuickCheck&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-4&quot;&gt;&lt;a href=&quot;#cb1-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Test.QuickCheck.Monadic&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-5&quot;&gt;&lt;a href=&quot;#cb1-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Data.Complex&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-6&quot;&gt;&lt;a href=&quot;#cb1-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-7&quot;&gt;&lt;a href=&quot;#cb1-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;co&quot;&gt;-- inline-r imports&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-8&quot;&gt;&lt;a href=&quot;#cb1-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;qualified&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Foreign.R&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;R&lt;/span&gt; (cast)&lt;/span&gt;
&lt;span id=&quot;cb1-9&quot;&gt;&lt;a href=&quot;#cb1-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Foreign.R.Type&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;R&lt;/span&gt; &lt;span class=&quot;co&quot;&gt;-- SComplex&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-10&quot;&gt;&lt;a href=&quot;#cb1-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;H.Prelude&lt;/span&gt; (runRegion, withEmbeddedR, defaultConfig)&lt;/span&gt;
&lt;span id=&quot;cb1-11&quot;&gt;&lt;a href=&quot;#cb1-11&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Language.R.QQ&lt;/span&gt; (r)&lt;/span&gt;
&lt;span id=&quot;cb1-12&quot;&gt;&lt;a href=&quot;#cb1-12&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Language.R.HExp&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;HExp&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;HExp&lt;/span&gt;(&lt;span class=&quot;dt&quot;&gt;Complex&lt;/span&gt;),hexp)&lt;/span&gt;
&lt;span id=&quot;cb1-13&quot;&gt;&lt;a href=&quot;#cb1-13&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Data.Vector.SEXP&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;R&lt;/span&gt; (toList)&lt;/span&gt;
&lt;span id=&quot;cb1-14&quot;&gt;&lt;a href=&quot;#cb1-14&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-15&quot;&gt;&lt;a href=&quot;#cb1-15&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;co&quot;&gt;-- the module we wrote in the previous article&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-16&quot;&gt;&lt;a href=&quot;#cb1-16&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;FFT&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-17&quot;&gt;&lt;a href=&quot;#cb1-17&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-18&quot;&gt;&lt;a href=&quot;#cb1-18&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;co&quot;&gt;-- Call R&amp;#39;s FFT&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-19&quot;&gt;&lt;a href=&quot;#cb1-19&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;r_fft ::&lt;/span&gt; [&lt;span class=&quot;dt&quot;&gt;Complex&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Double&lt;/span&gt;] &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;IO&lt;/span&gt; [&lt;span class=&quot;dt&quot;&gt;Complex&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Double&lt;/span&gt;]&lt;/span&gt;
&lt;span id=&quot;cb1-20&quot;&gt;&lt;a href=&quot;#cb1-20&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;r_fft nums &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; runRegion &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-21&quot;&gt;&lt;a href=&quot;#cb1-21&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  r_result1 &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; [r|fft(nums_hs)|]&lt;/span&gt;
&lt;span id=&quot;cb1-22&quot;&gt;&lt;a href=&quot;#cb1-22&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;let&lt;/span&gt; r_result2 &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; R.cast &lt;span class=&quot;dt&quot;&gt;R.SComplex&lt;/span&gt; r_result1&lt;/span&gt;
&lt;span id=&quot;cb1-23&quot;&gt;&lt;a href=&quot;#cb1-23&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;dt&quot;&gt;HExp.Complex&lt;/span&gt; r_result3 &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; hexp r_result2&lt;/span&gt;
&lt;span id=&quot;cb1-24&quot;&gt;&lt;a href=&quot;#cb1-24&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      r_result4 &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; R.toList r_result3&lt;/span&gt;
&lt;span id=&quot;cb1-25&quot;&gt;&lt;a href=&quot;#cb1-25&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;fu&quot;&gt;return&lt;/span&gt; r_result4&lt;/span&gt;
&lt;span id=&quot;cb1-26&quot;&gt;&lt;a href=&quot;#cb1-26&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-27&quot;&gt;&lt;a href=&quot;#cb1-27&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;main &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-28&quot;&gt;&lt;a href=&quot;#cb1-28&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  withEmbeddedR defaultConfig&lt;/span&gt;
&lt;span id=&quot;cb1-29&quot;&gt;&lt;a href=&quot;#cb1-29&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt; defaultMain&lt;/span&gt;
&lt;span id=&quot;cb1-30&quot;&gt;&lt;a href=&quot;#cb1-30&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt; testProperty &lt;span class=&quot;st&quot;&gt;&amp;quot;Haskell vs. R&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-31&quot;&gt;&lt;a href=&quot;#cb1-31&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; \(&lt;span class=&quot;ot&quot;&gt;nums ::&lt;/span&gt; [&lt;span class=&quot;dt&quot;&gt;Complex&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Double&lt;/span&gt;]) &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; monadicIO &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-32&quot;&gt;&lt;a href=&quot;#cb1-32&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-33&quot;&gt;&lt;a href=&quot;#cb1-33&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    r_result &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; run &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; r_fft nums&lt;/span&gt;
&lt;span id=&quot;cb1-34&quot;&gt;&lt;a href=&quot;#cb1-34&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-35&quot;&gt;&lt;a href=&quot;#cb1-35&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;kw&quot;&gt;let&lt;/span&gt; haskell_result &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;fst&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; fft nums&lt;/span&gt;
&lt;span id=&quot;cb1-36&quot;&gt;&lt;a href=&quot;#cb1-36&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-37&quot;&gt;&lt;a href=&quot;#cb1-37&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    assert &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-38&quot;&gt;&lt;a href=&quot;#cb1-38&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      Prelude.length r_result &lt;span class=&quot;op&quot;&gt;==&lt;/span&gt; Prelude.length haskell_result &lt;span class=&quot;op&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-39&quot;&gt;&lt;a href=&quot;#cb1-39&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;fu&quot;&gt;all&lt;/span&gt; ((&lt;span class=&quot;op&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;fl&quot;&gt;1e-8&lt;/span&gt;) &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt; magnitude) (&lt;span class=&quot;fu&quot;&gt;zipWith&lt;/span&gt; (&lt;span class=&quot;op&quot;&gt;-&lt;/span&gt;) r_result haskell_result)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The result?&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Haskell vs. R: OK (0.28s)
  +++ OK, passed 100 tests.

All 1 tests passed (0.28s)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That’s reassuring; at least we are computing the right thing. Now
let’s see if we’ve managed to stay within our &lt;span
class=&quot;math inline&quot;&gt;\(O(n \log n)\)&lt;/span&gt; bound.&lt;/p&gt;
&lt;h2 id=&quot;testing-complexity&quot;&gt;Testing complexity&lt;/h2&gt;
&lt;p&gt;Luckily, our implementation already records the number of arithmetic
operations it takes to compute the answer.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt; snd . fft $ replicate 13 1
312&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And we can follow this number as &lt;span
class=&quot;math inline&quot;&gt;\(n\)&lt;/span&gt; grows:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt; map (\n -&amp;gt; snd . fft $ replicate n 1) [1..20]
[0,4,12,16,40,36,84,48,144,100,220,96,312,196,420,128,544,324,684,240]&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;But these numbers don’t tell us much. How do we know if this is &lt;span
class=&quot;math inline&quot;&gt;\(\Theta(n \log n)\)&lt;/span&gt; or &lt;span
class=&quot;math inline&quot;&gt;\(\Theta(n^2)\)&lt;/span&gt;? For this, we will again turn
to R.&lt;/p&gt;
&lt;p&gt;R’s &lt;a
href=&quot;https://stat.ethz.ch/R-manual/R-devel/library/stats/html/lm.html&quot;&gt;lm&lt;/a&gt;
function approximates one value as a linear combination of other values.
In this case, we’ll try to find a linear combination of &lt;span
class=&quot;math inline&quot;&gt;\(n\)&lt;/span&gt;, &lt;span class=&quot;math inline&quot;&gt;\(n \log
n\)&lt;/span&gt;, and &lt;span class=&quot;math inline&quot;&gt;\(n^2\)&lt;/span&gt; that
approximates the number of operations it takes our FFT implementation to
complete on an input of size &lt;span class=&quot;math inline&quot;&gt;\(n\)&lt;/span&gt;. If
it turns out that the coefficient of &lt;span
class=&quot;math inline&quot;&gt;\(n^2\)&lt;/span&gt; in this combination is a
non-negligible positive number, then the complexity of our algorithm is
probably not &lt;span class=&quot;math inline&quot;&gt;\(O(n \log n)\)&lt;/span&gt;.&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb5&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb5-1&quot;&gt;&lt;a href=&quot;#cb5-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;{-# LANGUAGE QuasiQuotes #-}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-2&quot;&gt;&lt;a href=&quot;#cb5-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;H.Prelude&lt;/span&gt; (runRegion, withEmbeddedR, defaultConfig)&lt;/span&gt;
&lt;span id=&quot;cb5-3&quot;&gt;&lt;a href=&quot;#cb5-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;qualified&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;H.Prelude&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;H&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-4&quot;&gt;&lt;a href=&quot;#cb5-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Language.R.QQ&lt;/span&gt; (r)&lt;/span&gt;
&lt;span id=&quot;cb5-5&quot;&gt;&lt;a href=&quot;#cb5-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-6&quot;&gt;&lt;a href=&quot;#cb5-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;FFT&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-7&quot;&gt;&lt;a href=&quot;#cb5-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-8&quot;&gt;&lt;a href=&quot;#cb5-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;fft_ops ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Int&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Int&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-9&quot;&gt;&lt;a href=&quot;#cb5-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;fft_ops n &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;snd&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt; fft &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;replicate&lt;/span&gt; n &lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-10&quot;&gt;&lt;a href=&quot;#cb5-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-11&quot;&gt;&lt;a href=&quot;#cb5-11&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;analyze&lt;/span&gt;
&lt;span id=&quot;cb5-12&quot;&gt;&lt;a href=&quot;#cb5-12&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;  ::&lt;/span&gt; [&lt;span class=&quot;dt&quot;&gt;Int&lt;/span&gt;] &lt;span class=&quot;co&quot;&gt;-- sequence of n&amp;#39;s&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-13&quot;&gt;&lt;a href=&quot;#cb5-13&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;IO&lt;/span&gt; ()&lt;/span&gt;
&lt;span id=&quot;cb5-14&quot;&gt;&lt;a href=&quot;#cb5-14&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;analyze ns &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; runRegion &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-15&quot;&gt;&lt;a href=&quot;#cb5-15&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;let&lt;/span&gt; ops &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;map&lt;/span&gt; fft_ops ns&lt;/span&gt;
&lt;span id=&quot;cb5-16&quot;&gt;&lt;a href=&quot;#cb5-16&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-17&quot;&gt;&lt;a href=&quot;#cb5-17&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      ns_dbl,&lt;span class=&quot;ot&quot;&gt; ops_dbl ::&lt;/span&gt; [&lt;span class=&quot;dt&quot;&gt;Double&lt;/span&gt;]&lt;/span&gt;
&lt;span id=&quot;cb5-18&quot;&gt;&lt;a href=&quot;#cb5-18&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      ns_dbl &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;map&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;fromIntegral&lt;/span&gt; ns&lt;/span&gt;
&lt;span id=&quot;cb5-19&quot;&gt;&lt;a href=&quot;#cb5-19&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      ops_dbl &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;map&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;fromIntegral&lt;/span&gt; ops&lt;/span&gt;
&lt;span id=&quot;cb5-20&quot;&gt;&lt;a href=&quot;#cb5-20&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-21&quot;&gt;&lt;a href=&quot;#cb5-21&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  H.print &lt;span class=&quot;op&quot;&gt;=&amp;lt;&amp;lt;&lt;/span&gt; [r| ops &amp;lt;- ops_dbl_hs; n &amp;lt;- ns_dbl_hs; lm(ops ~ I(n^2) + I(n*log(n)) + n)|]&lt;/span&gt;
&lt;span id=&quot;cb5-22&quot;&gt;&lt;a href=&quot;#cb5-22&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-23&quot;&gt;&lt;a href=&quot;#cb5-23&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;main &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; withEmbeddedR defaultConfig &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-24&quot;&gt;&lt;a href=&quot;#cb5-24&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  analyze [ &lt;span class=&quot;dv&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;^&lt;/span&gt;k   &lt;span class=&quot;op&quot;&gt;|&lt;/span&gt; k &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; [&lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;..&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;10&lt;/span&gt;]]&lt;/span&gt;
&lt;span id=&quot;cb5-25&quot;&gt;&lt;a href=&quot;#cb5-25&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  analyze [ &lt;span class=&quot;dv&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;*&lt;/span&gt;k&lt;span class=&quot;op&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;|&lt;/span&gt; k &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; [&lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;..&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;30&lt;/span&gt;]]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;First, we try &lt;span class=&quot;math inline&quot;&gt;\(n\)&lt;/span&gt;s which are
powers of 2. Then the number of points for evaluation halves (while
remaining even!) at each level of our divide-and-conquer algorithm.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Call:
lm(formula = ops ~ I(n^2) + I(n * log(n)) + n)

Coefficients:
  (Intercept)         I(n^2)  I(n * log(n))              n
    3.036e-13      1.840e-17      2.885e+00      3.399e-14&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The number of steps is rather well approximated by &lt;span
class=&quot;math inline&quot;&gt;\(2.885\, n \log n\)&lt;/span&gt;. That’s a win! (By the
way, can you tell or guess where the number 2.885 comes from?)&lt;/p&gt;
&lt;p&gt;But remember, the number of points only shrinks when it’s even. What
the number is odd from the very beginning? Then it’ll never reduce at
all!&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Call:
lm(formula = ops ~ I(n^2) + I(n * log(n)) + n)

Coefficients:
  (Intercept)         I(n^2)  I(n * log(n))              n
    2.657e-12      2.000e+00      1.834e-13     -2.000e+00&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Our fears are confirmed; this time the &lt;span class=&quot;math inline&quot;&gt;\(n
\log n\)&lt;/span&gt; coefficient is negligible, and the number of operations
appears to be &lt;span class=&quot;math inline&quot;&gt;\(2(n^2-n)\)&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;For an arbitrary number &lt;span class=&quot;math inline&quot;&gt;\(n\)&lt;/span&gt;, the
efficiency of the algorithm depends on the largest power of 2 that
divides &lt;span class=&quot;math inline&quot;&gt;\(n\)&lt;/span&gt;. If &lt;span
class=&quot;math inline&quot;&gt;\(n = 2^m q\)&lt;/span&gt;, where &lt;span
class=&quot;math inline&quot;&gt;\(m\)&lt;/span&gt; is odd, then &lt;span
class=&quot;math inline&quot;&gt;\(n\)&lt;/span&gt; will halve during the first &lt;span
class=&quot;math inline&quot;&gt;\(m\)&lt;/span&gt; steps, and then stabilize at &lt;span
class=&quot;math inline&quot;&gt;\(q\)&lt;/span&gt;.&lt;/p&gt;
&lt;h2 id=&quot;concluding-remarks-on-inline-r&quot;&gt;Concluding remarks on
inline-r&lt;/h2&gt;
&lt;p&gt;The way inline-r works is very cool. It takes advantage of some
unique features of R; for example, that the type of R’s AST and the type
of its runtime values is the same type, just like in Lisp.&lt;/p&gt;
&lt;p&gt;So the quasi-quote &lt;code&gt;[r|...|]&lt;/code&gt; works by calling a normal R
function that parses the expression and returns its AST as an R value.
Then inline-r traverses the AST, replaces metavariables like
&lt;code&gt;foo_hs&lt;/code&gt; by values dynamically constructed from
&lt;code&gt;foo&lt;/code&gt;, and passes the expression-as-a-value back to R for
evaluation.&lt;/p&gt;
&lt;p&gt;To learn more, refer to the paper &lt;a
href=&quot;https://ifl2014.github.io/submissions/ifl2014_submission_16.pdf&quot;&gt;Project
H: Programming R in Haskell&lt;/a&gt;. Also, if you understand Russian, listen
to &lt;a href=&quot;http://bananasandlenses.net/episode016&quot;&gt;our podcast&lt;/a&gt;
where we discuss inline-r with Alexander Vershilov, one of its
authors.&lt;/p&gt;
&lt;p&gt;On the other hand, the code using inline-r may get somewhat bulky, as
in the &lt;code&gt;r_fft&lt;/code&gt; function. It’s hard for me to say yet whether
this complexity is justified. The module organization is questionable;
in our first program, accessing fairly basic functionality required
importing 6 different modules. Finally, the documentation lacks in
content and organization.&lt;/p&gt;
&lt;p&gt;Yet this is a very impressive young project, and I would love to see
its continued development.&lt;/p&gt;
</description>
                        <pubDate>Sat, 05 Dec 2015 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2015-12-05-testing-fft</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2015-12-05-testing-fft.html</guid>
                </item>
        
                <item>
                        <title>Simple FFT in Haskell</title>
                        <description>&lt;p&gt;The article develops a simple implementation of the &lt;a
href=&quot;https://en.wikipedia.org/wiki/Fast_Fourier_transform&quot;&gt;fast Fourier
transform&lt;/a&gt; in Haskell.&lt;/p&gt;
&lt;p&gt;Raw performance of the algorithm is explicitly not a goal here; for
instance, I use things like &lt;code&gt;nub&lt;/code&gt;, &lt;code&gt;Writer&lt;/code&gt;, and
lists for simplicity. On the other hand, I do pay attention to the
algorithmic complexity in terms of the number of arithmetic operations
performed; the analysis thereof will be done in a subsequent
article.&lt;/p&gt;
&lt;h2 id=&quot;background&quot;&gt;Background&lt;/h2&gt;
&lt;p&gt;&lt;a
href=&quot;https://en.wikipedia.org/wiki/Discrete_Fourier_transform&quot;&gt;Discrete
Fourier transform&lt;/a&gt; turns &lt;span class=&quot;math inline&quot;&gt;\(n\)&lt;/span&gt;
complex numbers &lt;span
class=&quot;math inline&quot;&gt;\(a_0,a_1,\ldots,a_{n-1}\)&lt;/span&gt; into &lt;span
class=&quot;math inline&quot;&gt;\(n\)&lt;/span&gt; complex numbers&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;math display&quot;&gt;\[f_k = \sum_{l=0}^{n-1} e^{- 2 \pi i k l
/ n} a_l.\]&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;An alternative way to think about &lt;span
class=&quot;math inline&quot;&gt;\(f_k\)&lt;/span&gt; is as the values of the
polynomial&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;math display&quot;&gt;\[P(x)=\sum_{l=0}^{n-1} a_l
x^l\]&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;at &lt;span class=&quot;math inline&quot;&gt;\(n\)&lt;/span&gt; points &lt;span
class=&quot;math inline&quot;&gt;\(w^0,w^1,\ldots,w^{n-1}\)&lt;/span&gt;, where &lt;span
class=&quot;math inline&quot;&gt;\(w=e^{-2 \pi i / n}\)&lt;/span&gt; is a certain &lt;span
class=&quot;math inline&quot;&gt;\(n\)&lt;/span&gt;th primitive root of unity.&lt;/p&gt;
&lt;p&gt;The naive calculation requires &lt;span
class=&quot;math inline&quot;&gt;\(\Theta(n^2)\)&lt;/span&gt; operations; our goal is to
reduce that number to &lt;span class=&quot;math inline&quot;&gt;\(\Theta(n \log
n)\)&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;An excellent explanation of the algorithm (which inspired this
article in the first place) is given by Daniel Gusfield in &lt;a
href=&quot;http://csiflabs.cs.ucdavis.edu/~gusfield/&quot;&gt;his video lectures&lt;/a&gt;;
he calls it “the most important algorithm that most computer scientists
have never studied”. You only need to watch the first two lectures (and
maybe the beginning of the third one) to understand the algorithm and
this article.&lt;/p&gt;
&lt;h2 id=&quot;roots-of-unity&quot;&gt;Roots of unity&lt;/h2&gt;
&lt;p&gt;Roots of unity could in principle be represented in the Cartesian
form by the &lt;code&gt;Complex a&lt;/code&gt; type. However, that would make it
very hard to compare them for equality, which we are going to do to
achieve a subquadratic complexity.&lt;/p&gt;
&lt;p&gt;So here’s a small module just for representing these special complex
numbers in the polar form, taking advantage of the fact that their
absolute values are always 1 and their phases are rational multiples of
&lt;span class=&quot;math inline&quot;&gt;\(\pi\)&lt;/span&gt;.&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb1&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb1-1&quot;&gt;&lt;a href=&quot;#cb1-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;module&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;RootOfUnity&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-2&quot;&gt;&lt;a href=&quot;#cb1-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  ( &lt;span class=&quot;dt&quot;&gt;U&lt;/span&gt; &lt;span class=&quot;co&quot;&gt;-- abstract&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-3&quot;&gt;&lt;a href=&quot;#cb1-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  , mkU&lt;/span&gt;
&lt;span id=&quot;cb1-4&quot;&gt;&lt;a href=&quot;#cb1-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  , toComplex&lt;/span&gt;
&lt;span id=&quot;cb1-5&quot;&gt;&lt;a href=&quot;#cb1-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  , u_pow&lt;/span&gt;
&lt;span id=&quot;cb1-6&quot;&gt;&lt;a href=&quot;#cb1-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  , u_sqr&lt;/span&gt;
&lt;span id=&quot;cb1-7&quot;&gt;&lt;a href=&quot;#cb1-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  ) &lt;span class=&quot;kw&quot;&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-8&quot;&gt;&lt;a href=&quot;#cb1-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-9&quot;&gt;&lt;a href=&quot;#cb1-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Data.Complex&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-10&quot;&gt;&lt;a href=&quot;#cb1-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-11&quot;&gt;&lt;a href=&quot;#cb1-11&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;co&quot;&gt;-- | U q corresponds to the complex number exp(2 i pi q)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-12&quot;&gt;&lt;a href=&quot;#cb1-12&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;newtype&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;U&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;U&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Rational&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-13&quot;&gt;&lt;a href=&quot;#cb1-13&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;deriving&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;Show&lt;/span&gt;, &lt;span class=&quot;dt&quot;&gt;Eq&lt;/span&gt;, &lt;span class=&quot;dt&quot;&gt;Ord&lt;/span&gt;)&lt;/span&gt;
&lt;span id=&quot;cb1-14&quot;&gt;&lt;a href=&quot;#cb1-14&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-15&quot;&gt;&lt;a href=&quot;#cb1-15&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;co&quot;&gt;-- | Convert a U number to the equivalent complex number&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-16&quot;&gt;&lt;a href=&quot;#cb1-16&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;toComplex ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Floating&lt;/span&gt; a &lt;span class=&quot;ot&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;U&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Complex&lt;/span&gt; a&lt;/span&gt;
&lt;span id=&quot;cb1-17&quot;&gt;&lt;a href=&quot;#cb1-17&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;toComplex (&lt;span class=&quot;dt&quot;&gt;U&lt;/span&gt; q) &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; mkPolar &lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt; (&lt;span class=&quot;dv&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;pi&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;realToFrac&lt;/span&gt; q)&lt;/span&gt;
&lt;span id=&quot;cb1-18&quot;&gt;&lt;a href=&quot;#cb1-18&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-19&quot;&gt;&lt;a href=&quot;#cb1-19&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;co&quot;&gt;-- | Smart constructor for U numbers; automatically performs normalization&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-20&quot;&gt;&lt;a href=&quot;#cb1-20&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;mkU ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Rational&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;U&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-21&quot;&gt;&lt;a href=&quot;#cb1-21&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;mkU q &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;U&lt;/span&gt; (q &lt;span class=&quot;op&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;realToFrac&lt;/span&gt; (&lt;span class=&quot;fu&quot;&gt;floor&lt;/span&gt; q))&lt;/span&gt;
&lt;span id=&quot;cb1-22&quot;&gt;&lt;a href=&quot;#cb1-22&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-23&quot;&gt;&lt;a href=&quot;#cb1-23&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;co&quot;&gt;-- | Raise a U number to a power&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-24&quot;&gt;&lt;a href=&quot;#cb1-24&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;u_pow ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;U&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Integer&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;U&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-25&quot;&gt;&lt;a href=&quot;#cb1-25&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;u_pow (&lt;span class=&quot;dt&quot;&gt;U&lt;/span&gt; q) p &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; mkU (&lt;span class=&quot;fu&quot;&gt;fromIntegral&lt;/span&gt; p&lt;span class=&quot;op&quot;&gt;*&lt;/span&gt;q)&lt;/span&gt;
&lt;span id=&quot;cb1-26&quot;&gt;&lt;a href=&quot;#cb1-26&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-27&quot;&gt;&lt;a href=&quot;#cb1-27&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;co&quot;&gt;-- | Square a U number&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-28&quot;&gt;&lt;a href=&quot;#cb1-28&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;u_sqr ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;U&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;U&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-29&quot;&gt;&lt;a href=&quot;#cb1-29&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;u_sqr x &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; u_pow x &lt;span class=&quot;dv&quot;&gt;2&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;fast-fourier-transform&quot;&gt;Fast Fourier transform&lt;/h2&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb2&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb2-1&quot;&gt;&lt;a href=&quot;#cb2-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;{-# LANGUAGE ScopedTypeVariables #-}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-2&quot;&gt;&lt;a href=&quot;#cb2-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;module&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;FFT&lt;/span&gt; (fft) &lt;span class=&quot;kw&quot;&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-3&quot;&gt;&lt;a href=&quot;#cb2-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-4&quot;&gt;&lt;a href=&quot;#cb2-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Data.Complex&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-5&quot;&gt;&lt;a href=&quot;#cb2-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Data.Ratio&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-6&quot;&gt;&lt;a href=&quot;#cb2-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Data.Monoid&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-7&quot;&gt;&lt;a href=&quot;#cb2-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;qualified&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Data.Map&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Map&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-8&quot;&gt;&lt;a href=&quot;#cb2-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Data.List&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-9&quot;&gt;&lt;a href=&quot;#cb2-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Data.Bifunctor&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-10&quot;&gt;&lt;a href=&quot;#cb2-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Control.Monad.Trans.Writer&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-11&quot;&gt;&lt;a href=&quot;#cb2-11&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;RootOfUnity&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;So we want to evaluate the polynomial &lt;span
class=&quot;math inline&quot;&gt;\(P(x)=\sum_{l=0}^{n-1}a_lx^l\)&lt;/span&gt; at points
&lt;span class=&quot;math inline&quot;&gt;\(w^k\)&lt;/span&gt;. The trick is to represent
&lt;span class=&quot;math inline&quot;&gt;\(P(x)\)&lt;/span&gt; as &lt;span
class=&quot;math inline&quot;&gt;\(A_e(x^2) + x A_o(x^2)\)&lt;/span&gt;, where &lt;span
class=&quot;math inline&quot;&gt;\(A_e(x)=a_0+a_2 x + \ldots\)&lt;/span&gt; and &lt;span
class=&quot;math inline&quot;&gt;\(A_o(x)=a_1+a_3 x + \ldots\)&lt;/span&gt; are polynomials
constructed out of the even-numbered and odd-numbered coefficients of
&lt;span class=&quot;math inline&quot;&gt;\(P\)&lt;/span&gt;, respectively.&lt;/p&gt;
&lt;p&gt;When &lt;span class=&quot;math inline&quot;&gt;\(x\)&lt;/span&gt; is a root of unity, so is
&lt;span class=&quot;math inline&quot;&gt;\(x^2\)&lt;/span&gt;; this allows us to apply the
algorithm recursively to evaluate &lt;span
class=&quot;math inline&quot;&gt;\(A_e\)&lt;/span&gt; and &lt;span
class=&quot;math inline&quot;&gt;\(A_o\)&lt;/span&gt; for the squared numbers.&lt;/p&gt;
&lt;p&gt;But the real boon comes when &lt;span class=&quot;math inline&quot;&gt;\(n\)&lt;/span&gt;
is even; then there will be half as many of these squared numbers,
because &lt;span class=&quot;math inline&quot;&gt;\(w^k\)&lt;/span&gt; and &lt;span
class=&quot;math inline&quot;&gt;\(w^{k+n/2}\)&lt;/span&gt;, when squared, both give the
same number &lt;span class=&quot;math inline&quot;&gt;\(w^{2k}\)&lt;/span&gt;. This is when
the divide and conquer strategy really pays off.&lt;/p&gt;
&lt;p&gt;We will represent a polynomial &lt;span
class=&quot;math inline&quot;&gt;\(\sum_{l=0}^{n-1}a_lx^l\)&lt;/span&gt; in Haskell as a
list of coefficients &lt;code&gt;[a_0,a_1,...]&lt;/code&gt;, starting with &lt;span
class=&quot;math inline&quot;&gt;\(a_0\)&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;To be able to split a polynomial into the even and odd parts, let’s
define a corresponding list function&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb3&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb3-1&quot;&gt;&lt;a href=&quot;#cb3-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;split ::&lt;/span&gt; [a] &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; ([a], [a])&lt;/span&gt;
&lt;span id=&quot;cb3-2&quot;&gt;&lt;a href=&quot;#cb3-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;split &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;foldr&lt;/span&gt; f ([], [])&lt;/span&gt;
&lt;span id=&quot;cb3-3&quot;&gt;&lt;a href=&quot;#cb3-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-4&quot;&gt;&lt;a href=&quot;#cb3-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    f a (r1, r2) &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; (a &lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; r2, r1)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;(I think I learned the idea of this elegant implementation from &lt;a
href=&quot;https://idontgetoutmuch.wordpress.com/&quot;&gt;Dominic Steinitz&lt;/a&gt;.)&lt;/p&gt;
&lt;p&gt;Now, the core of the algorithm: a function that evaluates a
polynomial at a given list of points on the unit circle. It tracks the
number of performed arithmetic operations through a &lt;code&gt;Writer&lt;/code&gt;
monad over the &lt;code&gt;Sum&lt;/code&gt; monoid.&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb4&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb4-1&quot;&gt;&lt;a href=&quot;#cb4-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;evalFourier&lt;/span&gt;
&lt;span id=&quot;cb4-2&quot;&gt;&lt;a href=&quot;#cb4-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;  ::&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;forall&lt;/span&gt; a &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;RealFloat&lt;/span&gt; a&lt;/span&gt;
&lt;span id=&quot;cb4-3&quot;&gt;&lt;a href=&quot;#cb4-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;ot&quot;&gt;=&amp;gt;&lt;/span&gt; [&lt;span class=&quot;dt&quot;&gt;Complex&lt;/span&gt; a] &lt;span class=&quot;co&quot;&gt;-- ^ polynomial coefficients, starting from a_0&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-4&quot;&gt;&lt;a href=&quot;#cb4-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; [&lt;span class=&quot;dt&quot;&gt;U&lt;/span&gt;] &lt;span class=&quot;co&quot;&gt;-- ^ points at which to evaluate the polynomial&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-5&quot;&gt;&lt;a href=&quot;#cb4-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Writer&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;Sum&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Int&lt;/span&gt;) [&lt;span class=&quot;dt&quot;&gt;Complex&lt;/span&gt; a]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;If the polynomial is a constant, there’s not much to calculate. This
is our base case.&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb5&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb5-1&quot;&gt;&lt;a href=&quot;#cb5-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;evalFourier []  pts &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;&amp;lt;$&lt;/span&gt; pts&lt;/span&gt;
&lt;span id=&quot;cb5-2&quot;&gt;&lt;a href=&quot;#cb5-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;evalFourier [c] pts &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; c &lt;span class=&quot;op&quot;&gt;&amp;lt;$&lt;/span&gt; pts&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Otherwise, use the recursive algorithm outlined above.&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb6&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb6-1&quot;&gt;&lt;a href=&quot;#cb6-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;evalFourier coeffs pts &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-2&quot;&gt;&lt;a href=&quot;#cb6-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;let&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-3&quot;&gt;&lt;a href=&quot;#cb6-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    squares &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; nub &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; u_sqr &lt;span class=&quot;op&quot;&gt;&amp;lt;$&amp;gt;&lt;/span&gt; pts &lt;span class=&quot;co&quot;&gt;-- values of x^2&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-4&quot;&gt;&lt;a href=&quot;#cb6-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    (even_coeffs, odd_coeffs) &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; split coeffs&lt;/span&gt;
&lt;span id=&quot;cb6-5&quot;&gt;&lt;a href=&quot;#cb6-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  even_values &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; evalFourier even_coeffs squares&lt;/span&gt;
&lt;span id=&quot;cb6-6&quot;&gt;&lt;a href=&quot;#cb6-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  odd_values &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; evalFourier odd_coeffs squares&lt;/span&gt;
&lt;span id=&quot;cb6-7&quot;&gt;&lt;a href=&quot;#cb6-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-8&quot;&gt;&lt;a href=&quot;#cb6-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;let&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-9&quot;&gt;&lt;a href=&quot;#cb6-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;co&quot;&gt;-- a mapping from x^2 to (A_e(x^2), A_o(x^2))&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-10&quot;&gt;&lt;a href=&quot;#cb6-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    square_map &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-11&quot;&gt;&lt;a href=&quot;#cb6-11&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      Map.fromList&lt;/span&gt;
&lt;span id=&quot;cb6-12&quot;&gt;&lt;a href=&quot;#cb6-12&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;zip&lt;/span&gt; squares&lt;/span&gt;
&lt;span id=&quot;cb6-13&quot;&gt;&lt;a href=&quot;#cb6-13&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;zip&lt;/span&gt; even_values odd_values&lt;/span&gt;
&lt;span id=&quot;cb6-14&quot;&gt;&lt;a href=&quot;#cb6-14&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-15&quot;&gt;&lt;a href=&quot;#cb6-15&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;co&quot;&gt;-- evaluate the polynomial at a single point&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-16&quot;&gt;&lt;a href=&quot;#cb6-16&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;    eval1 ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;U&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Writer&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;Sum&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Int&lt;/span&gt;) (&lt;span class=&quot;dt&quot;&gt;Complex&lt;/span&gt; a)&lt;/span&gt;
&lt;span id=&quot;cb6-17&quot;&gt;&lt;a href=&quot;#cb6-17&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    eval1 x &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-18&quot;&gt;&lt;a href=&quot;#cb6-18&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;kw&quot;&gt;let&lt;/span&gt; (ye,yo) &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; (square_map &lt;span class=&quot;op&quot;&gt;Map.!&lt;/span&gt; u_sqr x)&lt;/span&gt;
&lt;span id=&quot;cb6-19&quot;&gt;&lt;a href=&quot;#cb6-19&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;          r &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; ye &lt;span class=&quot;op&quot;&gt;+&lt;/span&gt; toComplex x &lt;span class=&quot;op&quot;&gt;*&lt;/span&gt; yo&lt;/span&gt;
&lt;span id=&quot;cb6-20&quot;&gt;&lt;a href=&quot;#cb6-20&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      tell &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Sum&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;co&quot;&gt;-- this took two arithmetic operations&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-21&quot;&gt;&lt;a href=&quot;#cb6-21&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;fu&quot;&gt;return&lt;/span&gt; r&lt;/span&gt;
&lt;span id=&quot;cb6-22&quot;&gt;&lt;a href=&quot;#cb6-22&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-23&quot;&gt;&lt;a href=&quot;#cb6-23&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;fu&quot;&gt;mapM&lt;/span&gt; eval1 pts&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The actual FFT function is a simple wrapper around
&lt;code&gt;evalFourier&lt;/code&gt; which substitutes the specific points and
performs some simple conversions. It returns the result of the DFT and
the number of operations performed.&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb7&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb7-1&quot;&gt;&lt;a href=&quot;#cb7-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;fft ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;RealFloat&lt;/span&gt; a &lt;span class=&quot;ot&quot;&gt;=&amp;gt;&lt;/span&gt; [&lt;span class=&quot;dt&quot;&gt;Complex&lt;/span&gt; a] &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; ([&lt;span class=&quot;dt&quot;&gt;Complex&lt;/span&gt; a], &lt;span class=&quot;dt&quot;&gt;Int&lt;/span&gt;)&lt;/span&gt;
&lt;span id=&quot;cb7-2&quot;&gt;&lt;a href=&quot;#cb7-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;fft coeffs &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb7-3&quot;&gt;&lt;a href=&quot;#cb7-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  second getSum&lt;/span&gt;
&lt;span id=&quot;cb7-4&quot;&gt;&lt;a href=&quot;#cb7-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt; runWriter &lt;/span&gt;
&lt;span id=&quot;cb7-5&quot;&gt;&lt;a href=&quot;#cb7-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt; evalFourier coeffs &lt;/span&gt;
&lt;span id=&quot;cb7-6&quot;&gt;&lt;a href=&quot;#cb7-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;map&lt;/span&gt; (u_pow w)&lt;/span&gt;
&lt;span id=&quot;cb7-7&quot;&gt;&lt;a href=&quot;#cb7-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; [&lt;span class=&quot;dv&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;..&lt;/span&gt;n&lt;span class=&quot;op&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;]&lt;/span&gt;
&lt;span id=&quot;cb7-8&quot;&gt;&lt;a href=&quot;#cb7-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb7-9&quot;&gt;&lt;a href=&quot;#cb7-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    n &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; genericLength coeffs&lt;/span&gt;
&lt;span id=&quot;cb7-10&quot;&gt;&lt;a href=&quot;#cb7-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    w &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; mkU (&lt;span class=&quot;op&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;%&lt;/span&gt; n)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;!--

## Exercise

In `evalFourier`, `nub` is used to remove possible duplicates among $x^2$.
Note, however, that `nub` is itself $\Theta(n^2)$.
A more efficient (and fun!) way to get unique x-squares would be to query the set of keys
of `square_map`. Can you do that?
[Hint](2015-09-02-monadfix)

--&gt;
</description>
                        <pubDate>Fri, 04 Dec 2015 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2015-12-04-fft</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2015-12-04-fft.html</guid>
                </item>
        
                <item>
                        <title>Static linking with ghc</title>
                        <description>&lt;p&gt;Recently I needed to build a Haskell program that would run on my
DigitalOcean box. The problem was that my laptop’s Linux distro (Fedora
22) was different from my server’s distro (Debian jessie), and they had
different versions of shared libraries.&lt;/p&gt;
&lt;p&gt;I &lt;em&gt;could&lt;/em&gt; build my app directly on the server, but I decided
to go with static linking instead. I didn’t find a lot of information
about static linking with ghc on the internet, hence this article.&lt;/p&gt;
&lt;p&gt;First, let’s clarify something. There are two kinds of libraries any
Haskell program links against: Haskell libraries and non-Haskell (most
often, C) libraries. Haskell libraries are linked statically by default;
we don’t need to worry about them. ghc’s &lt;code&gt;-static&lt;/code&gt; and
&lt;code&gt;-dynamic&lt;/code&gt; flag affect that kind of linking.&lt;/p&gt;
&lt;p&gt;On the other hand, non-Haskell libraries are linked dynamically by
default. To change that, we need to pass the following options to
&lt;code&gt;ghc&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;-optl-static -optl-pthread&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If you are using &lt;a
href=&quot;https://github.com/commercialhaskell/stack&quot;&gt;stack&lt;/a&gt; (as I did),
the whole command becomes&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;stack build --ghc-options=&amp;#39;-optl-static -optl-pthread&amp;#39; --force-dirty&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;--force-dirty&lt;/code&gt; may be needed because stack may not
recognize the options change as a sufficient reason to re-run ghc; this
may get fixed in future versions of stack.&lt;/p&gt;
&lt;p&gt;The command may fail in case you don’t have some of the static
libraries installed. In my case, the dynamic version of the executable
had these dynamic dependencies (as reported by &lt;code&gt;ldd&lt;/code&gt;):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;linux-vdso.so.1 (0x00007ffcb20c2000)
librt.so.1 =&amp;gt; /lib64/librt.so.1 (0x00007fa435dc6000)
libutil.so.1 =&amp;gt; /lib64/libutil.so.1 (0x00007fa435bc3000)
libdl.so.2 =&amp;gt; /lib64/libdl.so.2 (0x00007fa4359be000)
libpcre.so.1 =&amp;gt; /lib64/libpcre.so.1 (0x00007fa43574e000)
libgmp.so.10 =&amp;gt; /lib64/libgmp.so.10 (0x00007fa4354d6000)
libm.so.6 =&amp;gt; /lib64/libm.so.6 (0x00007fa4351cd000)
libgcc_s.so.1 =&amp;gt; /lib64/libgcc_s.so.1 (0x00007fa434fb6000)
libc.so.6 =&amp;gt; /lib64/libc.so.6 (0x00007fa434bf6000)
libpthread.so.0 =&amp;gt; /lib64/libpthread.so.0 (0x00007fa4349d9000)
/lib64/ld-linux-x86-64.so.2 (0x000055571e53e000)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To satisfy them statically, I had to install only three Fedora
packages:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;pcre-static.x86_64
gmp-static.x86_64
glibc-static.x86_64&lt;/code&gt;&lt;/pre&gt;
</description>
                        <pubDate>Mon, 26 Oct 2015 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2015-10-26-static-linking-ghc</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2015-10-26-static-linking-ghc.html</guid>
                </item>
        
                <item>
                        <title>MonadFix example: compiling regular expressions
</title>
                        <description>&lt;div class=&quot;sourceCode&quot; id=&quot;cb1&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb1-1&quot;&gt;&lt;a href=&quot;#cb1-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;{-# LANGUAGE RecursiveDo, BangPatterns #-}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-2&quot;&gt;&lt;a href=&quot;#cb1-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Control.Applicative&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-3&quot;&gt;&lt;a href=&quot;#cb1-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Data.Function&lt;/span&gt; (fix)&lt;/span&gt;
&lt;span id=&quot;cb1-4&quot;&gt;&lt;a href=&quot;#cb1-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Data.IntMap&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;IntMap&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-5&quot;&gt;&lt;a href=&quot;#cb1-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Control.Monad.Fix&lt;/span&gt; (mfix)&lt;/span&gt;
&lt;span id=&quot;cb1-6&quot;&gt;&lt;a href=&quot;#cb1-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Control.Monad.Trans.State&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-7&quot;&gt;&lt;a href=&quot;#cb1-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Control.Monad.Trans.Class&lt;/span&gt; (lift)&lt;/span&gt;
&lt;span id=&quot;cb1-8&quot;&gt;&lt;a href=&quot;#cb1-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Text.Read&lt;/span&gt; (readMaybe)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;a
href=&quot;https://hackage.haskell.org/package/base-4.8.1.0/docs/Control-Monad-Fix.html&quot;&gt;MonadFix&lt;/a&gt;
is an odd beast; many Haskell programmers will never use it in their
careers. It is indeed very rarely that one needs MonadFix; and for that
reason, non-contrived cases where MonadFix &lt;em&gt;is&lt;/em&gt; needed are quite
interesting to consider.&lt;/p&gt;
&lt;p&gt;In this article, I’ll introduce MonadFix and show how it can be handy
for compiling the Kleene closure (also known as star or repetition) of
regular expressions.&lt;/p&gt;
&lt;h2 id=&quot;what-is-monadfix&quot;&gt;What is MonadFix?&lt;/h2&gt;
&lt;p&gt;If you hear about MonadFix for the first time, you might think that
it is needed to define recursive monadic actions, just like ordinary
&lt;code&gt;fix&lt;/code&gt; is used to define recursive functions. That would be a
mistake. In fact, &lt;code&gt;fix&lt;/code&gt; is just as applicable to monadic
actions as it is to functions:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb2&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb2-1&quot;&gt;&lt;a href=&quot;#cb2-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;guessNumber m &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; fix &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; \&lt;span class=&quot;fu&quot;&gt;repeat&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-2&quot;&gt;&lt;a href=&quot;#cb2-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;fu&quot;&gt;putStrLn&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;quot;Enter a guess&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-3&quot;&gt;&lt;a href=&quot;#cb2-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  n &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; readMaybe &lt;span class=&quot;op&quot;&gt;&amp;lt;$&amp;gt;&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;getLine&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-4&quot;&gt;&lt;a href=&quot;#cb2-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;if&lt;/span&gt; n &lt;span class=&quot;op&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Just&lt;/span&gt; m&lt;/span&gt;
&lt;span id=&quot;cb2-5&quot;&gt;&lt;a href=&quot;#cb2-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;kw&quot;&gt;then&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;putStrLn&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;quot;You guessed it!&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-6&quot;&gt;&lt;a href=&quot;#cb2-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;kw&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-7&quot;&gt;&lt;a href=&quot;#cb2-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;fu&quot;&gt;putStrLn&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;quot;You guessed wrong; try again&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-8&quot;&gt;&lt;a href=&quot;#cb2-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;fu&quot;&gt;repeat&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;So, what is &lt;code&gt;mfix&lt;/code&gt; for? First, recall that in Haskell, one
can create recursive definitions not just for functions (which makes
sense in other, non-lazy languages) or monadic actions, but for ordinary
data structures as well. This is known as cyclic (or circular, or
corecursive) definitions; and the technique itself is sometimes referred
to as tying the knot.&lt;/p&gt;
&lt;p&gt;The classic example of a cyclic definition is the (lazy, infinite)
list of Fibonacci numbers:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb3&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb3-1&quot;&gt;&lt;a href=&quot;#cb3-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;fib &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;zipWith&lt;/span&gt; (&lt;span class=&quot;op&quot;&gt;+&lt;/span&gt;) fib (&lt;span class=&quot;fu&quot;&gt;tail&lt;/span&gt; fib)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Cyclic definitions are themselves rare in day-to-day Haskell
programming; but occasionally, the right hand side will be not a pure
value, but a monadic computation that needs to be run in order to obtain
the value.&lt;/p&gt;
&lt;p&gt;Consider this (contrived) example, where we start the sequence with
an arbitrary number entered by the user:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb4&quot;&gt;&lt;pre
class=&quot;sourceCode haskell ignore&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb4-1&quot;&gt;&lt;a href=&quot;#cb4-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;fibIO1 &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-2&quot;&gt;&lt;a href=&quot;#cb4-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;fu&quot;&gt;putStrLn&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;quot;Enter the start number&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-3&quot;&gt;&lt;a href=&quot;#cb4-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  start &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;read&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;&amp;lt;$&amp;gt;&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;getLine&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-4&quot;&gt;&lt;a href=&quot;#cb4-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;fu&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; start &lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;zipWith&lt;/span&gt; (&lt;span class=&quot;op&quot;&gt;+&lt;/span&gt;) fibIO1 (&lt;span class=&quot;fu&quot;&gt;tail&lt;/span&gt; fibIO1)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This doesn’t typecheck because &lt;code&gt;fibIO&lt;/code&gt; is not a list; it’s
an IO action that produces a list.&lt;/p&gt;
&lt;p&gt;But if we try to run the computation, it doesn’t make much sense
either:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb5&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb5-1&quot;&gt;&lt;a href=&quot;#cb5-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;fibIO2 &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-2&quot;&gt;&lt;a href=&quot;#cb5-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;fu&quot;&gt;putStrLn&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;quot;Enter the start number&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-3&quot;&gt;&lt;a href=&quot;#cb5-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  start &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;read&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;&amp;lt;$&amp;gt;&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;getLine&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-4&quot;&gt;&lt;a href=&quot;#cb5-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  fib &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; fibIO2&lt;/span&gt;
&lt;span id=&quot;cb5-5&quot;&gt;&lt;a href=&quot;#cb5-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;fu&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; start &lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;zipWith&lt;/span&gt; (&lt;span class=&quot;op&quot;&gt;+&lt;/span&gt;) fib (&lt;span class=&quot;fu&quot;&gt;tail&lt;/span&gt; fib)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This version of &lt;code&gt;fibIO&lt;/code&gt; will ask you to enter the start
number &lt;em&gt;ad infinitum&lt;/em&gt; and never get to evaluating anything.&lt;/p&gt;
&lt;p&gt;Of course, the simplest thing to do would be to move IO out of the
recursive equation; that’s why I said the example was contrived. But
MonadFix gives another solution:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb6&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb6-1&quot;&gt;&lt;a href=&quot;#cb6-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;fibIO3 &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; mfix &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; \fib &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-2&quot;&gt;&lt;a href=&quot;#cb6-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;fu&quot;&gt;putStrLn&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;quot;Enter the start number&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-3&quot;&gt;&lt;a href=&quot;#cb6-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  start &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;read&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;&amp;lt;$&amp;gt;&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;getLine&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-4&quot;&gt;&lt;a href=&quot;#cb6-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;fu&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; start &lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;zipWith&lt;/span&gt; (&lt;span class=&quot;op&quot;&gt;+&lt;/span&gt;) fib (&lt;span class=&quot;fu&quot;&gt;tail&lt;/span&gt; fib)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Or, using the do-rec syntax:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb7&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb7-1&quot;&gt;&lt;a href=&quot;#cb7-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;fibIO4 &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb7-2&quot;&gt;&lt;a href=&quot;#cb7-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  rec&lt;/span&gt;
&lt;span id=&quot;cb7-3&quot;&gt;&lt;a href=&quot;#cb7-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    fib &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb7-4&quot;&gt;&lt;a href=&quot;#cb7-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;fu&quot;&gt;putStrLn&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;quot;Enter the start number&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb7-5&quot;&gt;&lt;a href=&quot;#cb7-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      start &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;read&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;&amp;lt;$&amp;gt;&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;getLine&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb7-6&quot;&gt;&lt;a href=&quot;#cb7-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;fu&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; start &lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;zipWith&lt;/span&gt; (&lt;span class=&quot;op&quot;&gt;+&lt;/span&gt;) fib (&lt;span class=&quot;fu&quot;&gt;tail&lt;/span&gt; fib)&lt;/span&gt;
&lt;span id=&quot;cb7-7&quot;&gt;&lt;a href=&quot;#cb7-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;fu&quot;&gt;return&lt;/span&gt; fib&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;compiling-regular-expressions&quot;&gt;Compiling regular
expressions&lt;/h2&gt;
&lt;p&gt;As promised, I am going to show you an example usage of MonadFix that
solved a problem other than “how could I use MonadFix?”. This came up in
my work on &lt;a
href=&quot;https://hackage.haskell.org/package/regex-applicative&quot;&gt;regex-applicative&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;For a simplified presentation, let’s consider this type of regular
expressions:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb8&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb8-1&quot;&gt;&lt;a href=&quot;#cb8-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;RE&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb8-2&quot;&gt;&lt;a href=&quot;#cb8-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Sym&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Char&lt;/span&gt;  &lt;span class=&quot;co&quot;&gt;-- symbol&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb8-3&quot;&gt;&lt;a href=&quot;#cb8-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;op&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Seq&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;RE&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;RE&lt;/span&gt; &lt;span class=&quot;co&quot;&gt;-- sequence&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb8-4&quot;&gt;&lt;a href=&quot;#cb8-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;op&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Alt&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;RE&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;RE&lt;/span&gt; &lt;span class=&quot;co&quot;&gt;-- alternative&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb8-5&quot;&gt;&lt;a href=&quot;#cb8-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;op&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Rep&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;RE&lt;/span&gt;    &lt;span class=&quot;co&quot;&gt;-- repetition&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Our goal is to compile a regular expression into a corresponding NFA.
The states will be represented by integer numbers. State 0 corresponds
to successful completion; and each &lt;code&gt;Sym&lt;/code&gt; inside a regex will
have a unique positive state in which we are expecting the corresponding
character.&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb9&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb9-1&quot;&gt;&lt;a href=&quot;#cb9-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;NFAState&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Int&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The NFA will be represented by a map&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb10&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb10-1&quot;&gt;&lt;a href=&quot;#cb10-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;NFA&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;IntMap&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;Char&lt;/span&gt;, [&lt;span class=&quot;dt&quot;&gt;NFAState&lt;/span&gt;])&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;where each state is mapped to the characters expected at that state
and the list of states where we go in case we get the expected
character.&lt;/p&gt;
&lt;p&gt;To compile a regular expression, we’ll take as an argument the list
of states to proceed to when the regular expression as a whole succeeds
(otherwise we’d have to compile each subexpression separately and then
glue NFAs together). This is essentially the continuation-passing style;
only instead of functions, our continuations are NFA states.&lt;/p&gt;
&lt;p&gt;During the compilation, we’ll use a stack of two State monads: one to
assign sequential state numbers to &lt;code&gt;Sym&lt;/code&gt;s; the other to keep
track of the currently constructred NFA.&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb11&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb11-1&quot;&gt;&lt;a href=&quot;#cb11-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;co&quot;&gt;-- Returns the list of start states and the transition table&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb11-2&quot;&gt;&lt;a href=&quot;#cb11-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;compile ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;RE&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; ([&lt;span class=&quot;dt&quot;&gt;NFAState&lt;/span&gt;], &lt;span class=&quot;dt&quot;&gt;NFA&lt;/span&gt;)&lt;/span&gt;
&lt;span id=&quot;cb11-3&quot;&gt;&lt;a href=&quot;#cb11-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;compile re &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; runState (evalStateT (go re [&lt;span class=&quot;dv&quot;&gt;0&lt;/span&gt;]) &lt;span class=&quot;dv&quot;&gt;0&lt;/span&gt;) IntMap.empty&lt;/span&gt;
&lt;span id=&quot;cb11-4&quot;&gt;&lt;a href=&quot;#cb11-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb11-5&quot;&gt;&lt;a href=&quot;#cb11-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;co&quot;&gt;-- go accepts exit states, returns entry states&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb11-6&quot;&gt;&lt;a href=&quot;#cb11-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;go ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;RE&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; [&lt;span class=&quot;dt&quot;&gt;NFAState&lt;/span&gt;] &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;StateT&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;NFAState&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;State&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;NFA&lt;/span&gt;) [&lt;span class=&quot;dt&quot;&gt;NFAState&lt;/span&gt;]&lt;/span&gt;
&lt;span id=&quot;cb11-7&quot;&gt;&lt;a href=&quot;#cb11-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;go re exitStates &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb11-8&quot;&gt;&lt;a href=&quot;#cb11-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;case&lt;/span&gt; re &lt;span class=&quot;kw&quot;&gt;of&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb11-9&quot;&gt;&lt;a href=&quot;#cb11-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;dt&quot;&gt;Sym&lt;/span&gt; c &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb11-10&quot;&gt;&lt;a href=&quot;#cb11-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;op&quot;&gt;!&lt;/span&gt;freshState &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; gets (&lt;span class=&quot;op&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;); put freshState&lt;/span&gt;
&lt;span id=&quot;cb11-11&quot;&gt;&lt;a href=&quot;#cb11-11&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      lift &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; modify&amp;#39; (IntMap.insert freshState (c, exitStates))&lt;/span&gt;
&lt;span id=&quot;cb11-12&quot;&gt;&lt;a href=&quot;#cb11-12&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;fu&quot;&gt;return&lt;/span&gt; [freshState]&lt;/span&gt;
&lt;span id=&quot;cb11-13&quot;&gt;&lt;a href=&quot;#cb11-13&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;dt&quot;&gt;Alt&lt;/span&gt; r1 r2 &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; (&lt;span class=&quot;op&quot;&gt;++&lt;/span&gt;) &lt;span class=&quot;op&quot;&gt;&amp;lt;$&amp;gt;&lt;/span&gt; go r1 exitStates &lt;span class=&quot;op&quot;&gt;&amp;lt;*&amp;gt;&lt;/span&gt; go r2 exitStates&lt;/span&gt;
&lt;span id=&quot;cb11-14&quot;&gt;&lt;a href=&quot;#cb11-14&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;dt&quot;&gt;Seq&lt;/span&gt; r1 r2 &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; go r1 &lt;span class=&quot;op&quot;&gt;=&amp;lt;&amp;lt;&lt;/span&gt; go r2 exitStates&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This was easy so far: alternatives share their exit states and their
entry states are combined; and consequtive subexpressions are chained.
But how do we compile &lt;code&gt;Rep&lt;/code&gt;? The exit states of the repeated
subexpression should become its own entry states; but we don’t know the
entry states until we compile it!&lt;/p&gt;
&lt;p&gt;And this is precisely where MonadFix (or recursive do) comes in:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb12&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb12-1&quot;&gt;&lt;a href=&quot;#cb12-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;dt&quot;&gt;Rep&lt;/span&gt; r &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb12-2&quot;&gt;&lt;a href=&quot;#cb12-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      rec&lt;/span&gt;
&lt;span id=&quot;cb12-3&quot;&gt;&lt;a href=&quot;#cb12-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;        &lt;span class=&quot;kw&quot;&gt;let&lt;/span&gt; allEntryStates &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; ownEntryStates &lt;span class=&quot;op&quot;&gt;++&lt;/span&gt; exitStates&lt;/span&gt;
&lt;span id=&quot;cb12-4&quot;&gt;&lt;a href=&quot;#cb12-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;        ownEntryStates &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; go r allEntryStates&lt;/span&gt;
&lt;span id=&quot;cb12-5&quot;&gt;&lt;a href=&quot;#cb12-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;fu&quot;&gt;return&lt;/span&gt; allEntryStates&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Why does this circular definition work? If we unwrap the
&lt;code&gt;State&lt;/code&gt; types, we’ll see that the &lt;code&gt;go&lt;/code&gt; function
actually computes a triple of three non-strict fields:&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;The last used state number&lt;/li&gt;
&lt;li&gt;The list of entry states&lt;/li&gt;
&lt;li&gt;The NFA map&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The elements of the triple may depend on each other as long as there
are no actual loops during evaluation. One can check that the fields can
be indeed evaluated linearly in the order in which they are listed
above:&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;The used state numbers at each step depend only on the regular
expression itself, so it can be computed wihtout knowing the other two
fields.&lt;/li&gt;
&lt;li&gt;The list of entry states relies only on the state number
information; it doesn’t need to know anything about the NFA
transitions.&lt;/li&gt;
&lt;li&gt;The NFA table needs to know the entry and exit states; but that is
fine, we can go ahead and compute that information without creating any
reverse data dependencies.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;further-reading&quot;&gt;Further reading&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;http://wall.org/~lewis/2013/10/15/asm-monad.html&quot;&gt;An ASM
Monad&lt;/a&gt; – a similar example from a different domain.&lt;/p&gt;
&lt;p&gt;Oliver Charles’s &lt;a
href=&quot;https://ocharles.org.uk/blog/posts/2014-12-09-recursive-do.html&quot;&gt;24
Days of GHC Extensions: Recursive Do&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a
href=&quot;http://digitalcommons.ohsu.edu/cgi/viewcontent.cgi?article=1163&amp;amp;context=etd&quot;&gt;Levent
Erkok’s thesis&lt;/a&gt; which contains all you need to know about MonadFix,
including several other examples.&lt;/p&gt;
&lt;p&gt;Todd Wilson points out that Douglas McIlroy describes a similar
regular expression compilation technique in his 2004 JFP Functional
Pearl &lt;a href=&quot;http://www.cs.dartmouth.edu/~doug/nfa.ps.gz&quot;&gt;Enumerating
the strings of regular languages&lt;/a&gt;. Like this article, Douglas’s paper
uses a circular definition when compiling the Kleene closure. But the
circular definition is not monadic there: instead of using the State
monad, Douglas passes the state around by hand.&lt;/p&gt;
</description>
                        <pubDate>Wed, 02 Sep 2015 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2015-09-02-monadfix</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2015-09-02-monadfix.html</guid>
                </item>
        
                <item>
                        <title>Better YAML parsing</title>
                        <description>&lt;p&gt;If you need to parse a YAML file in Haskell today, you will probably
reach for Michael Snoyman’s &lt;a
href=&quot;https://hackage.haskell.org/package/yaml&quot;&gt;yaml&lt;/a&gt; package.&lt;/p&gt;
&lt;p&gt;That parser works in two stages.&lt;/p&gt;
&lt;p&gt;During the first stage, it parses YAML into a generic representation,
such as an array of dictionaries of strings. For this, the yaml package
uses the libyaml C library written by Kirill Simonov.&lt;/p&gt;
&lt;p&gt;During the second stage, the generic representation is converted into
the application-specific Haskell type. For instance, an abstract
dictionary may be mapped to a record type.&lt;/p&gt;
&lt;p&gt;This idea of two-stage parsing is borrowed from the &lt;a
href=&quot;https://hackage.haskell.org/package/aeson&quot;&gt;aeson&lt;/a&gt; package,
which parses JSON in a similar way. And because JSON’s and YAML’s data
models are similar, the yaml package borrows from Aeson not only the
above idea but also the generic representation and the machinery to
convert it to Haskell types.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/img/yaml.svg&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Thanks to this approach, if you have a &lt;code&gt;FromJSON&lt;/code&gt; instance
for a type, you can deserialize this type not only from JSON but also
from the more human readable and writable YAML.&lt;/p&gt;
&lt;p&gt;But there is a downside, too. Because Aeson’s primary goal is
performance, it doesn’t try to provide good error messages or even
validate the input beyond what’s necessary. This is not a problem for
JSON because it is typically generated by programs.&lt;/p&gt;
&lt;p&gt;But YAML is often written by humans, so it is important to detect
possible mistakes and report them clearly.&lt;/p&gt;
&lt;h2 id=&quot;example&quot;&gt;Example&lt;/h2&gt;
&lt;p&gt;Consider a Haskell type representing a shopping cart item:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb1&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb1-1&quot;&gt;&lt;a href=&quot;#cb1-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;{-# LANGUAGE OverloadedStrings #-}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-2&quot;&gt;&lt;a href=&quot;#cb1-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Data.Aeson&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;FromJSON&lt;/span&gt;(..), withObject, withText, (.:), (.:?), (.!=))&lt;/span&gt;
&lt;span id=&quot;cb1-3&quot;&gt;&lt;a href=&quot;#cb1-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Data.Yaml&lt;/span&gt; (decodeEither)&lt;/span&gt;
&lt;span id=&quot;cb1-4&quot;&gt;&lt;a href=&quot;#cb1-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Data.Text&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;Text&lt;/span&gt;)&lt;/span&gt;
&lt;span id=&quot;cb1-5&quot;&gt;&lt;a href=&quot;#cb1-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Control.Applicative&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-6&quot;&gt;&lt;a href=&quot;#cb1-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-7&quot;&gt;&lt;a href=&quot;#cb1-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Item&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Item&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-8&quot;&gt;&lt;a href=&quot;#cb1-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;dt&quot;&gt;Text&lt;/span&gt; &lt;span class=&quot;co&quot;&gt;-- title&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-9&quot;&gt;&lt;a href=&quot;#cb1-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;dt&quot;&gt;Int&lt;/span&gt; &lt;span class=&quot;co&quot;&gt;-- quantity&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-10&quot;&gt;&lt;a href=&quot;#cb1-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;deriving&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Show&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;In YAML, an &lt;code&gt;Item&lt;/code&gt; may be written as:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb2&quot;&gt;&lt;pre
class=&quot;sourceCode yaml&quot;&gt;&lt;code class=&quot;sourceCode yaml&quot;&gt;&lt;span id=&quot;cb2-1&quot;&gt;&lt;a href=&quot;#cb2-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;fu&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;kw&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;at&quot;&gt; Shampoo&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-2&quot;&gt;&lt;a href=&quot;#cb2-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;fu&quot;&gt;quantity&lt;/span&gt;&lt;span class=&quot;kw&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;at&quot;&gt; &lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;100&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;In our application, most of the time the quantity will be 1, so we
will allow two alternative simplified forms. In the first form, the
&lt;code&gt;quantity&lt;/code&gt; field is omitted and defaulted to 1:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb3&quot;&gt;&lt;pre
class=&quot;sourceCode yaml&quot;&gt;&lt;code class=&quot;sourceCode yaml&quot;&gt;&lt;span id=&quot;cb3-1&quot;&gt;&lt;a href=&quot;#cb3-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;fu&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;kw&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;at&quot;&gt; Shampoo&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;In the second form, the object will be flattened to a bare
string:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb4&quot;&gt;&lt;pre
class=&quot;sourceCode yaml&quot;&gt;&lt;code class=&quot;sourceCode yaml&quot;&gt;&lt;span id=&quot;cb4-1&quot;&gt;&lt;a href=&quot;#cb4-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;at&quot;&gt;Shampoo&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Here’s a reasonably idiomatic way to write an Aeson parser for this
format:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb5&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb5-1&quot;&gt;&lt;a href=&quot;#cb5-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;defaultQuantity ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Int&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-2&quot;&gt;&lt;a href=&quot;#cb5-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;defaultQuantity &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-3&quot;&gt;&lt;a href=&quot;#cb5-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-4&quot;&gt;&lt;a href=&quot;#cb5-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;instance&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;FromJSON&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Item&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-5&quot;&gt;&lt;a href=&quot;#cb5-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  parseJSON v &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; parseObject v &lt;span class=&quot;op&quot;&gt;&amp;lt;|&amp;gt;&lt;/span&gt; parseString v&lt;/span&gt;
&lt;span id=&quot;cb5-6&quot;&gt;&lt;a href=&quot;#cb5-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;kw&quot;&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-7&quot;&gt;&lt;a href=&quot;#cb5-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      parseObject &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; withObject &lt;span class=&quot;st&quot;&gt;&amp;quot;object&amp;quot;&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; \o &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-8&quot;&gt;&lt;a href=&quot;#cb5-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;        &lt;span class=&quot;dt&quot;&gt;Item&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;&amp;lt;$&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-9&quot;&gt;&lt;a href=&quot;#cb5-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;          o &lt;span class=&quot;op&quot;&gt;.:&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;quot;title&amp;quot;&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;&amp;lt;*&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-10&quot;&gt;&lt;a href=&quot;#cb5-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;          o &lt;span class=&quot;op&quot;&gt;.:?&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;quot;quantity&amp;quot;&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;.!=&lt;/span&gt; defaultQuantity&lt;/span&gt;
&lt;span id=&quot;cb5-11&quot;&gt;&lt;a href=&quot;#cb5-11&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;        &lt;/span&gt;
&lt;span id=&quot;cb5-12&quot;&gt;&lt;a href=&quot;#cb5-12&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      parseString &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; withText &lt;span class=&quot;st&quot;&gt;&amp;quot;string&amp;quot;&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; \t &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-13&quot;&gt;&lt;a href=&quot;#cb5-13&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;        &lt;span class=&quot;fu&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Item&lt;/span&gt; t defaultQuantity&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;With this example, I can now demonstrate the two weak spots of Aeson
parsing: insufficient input validation and confusing error messages.&lt;/p&gt;
&lt;h3 id=&quot;validation&quot;&gt;Validation&lt;/h3&gt;
&lt;p&gt;The following YAML parses successfully. But does the resulting
&lt;code&gt;Item&lt;/code&gt; match your expectations?&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb6&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb6-1&quot;&gt;&lt;a href=&quot;#cb6-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;decodeEither &lt;span class=&quot;st&quot;&gt;&amp;quot;{title: Shampoo, quanity: 2}&amp;quot;&lt;/span&gt;&lt;span class=&quot;ot&quot;&gt; ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Either&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Item&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;pre&gt;&lt;code&gt;Right (Item &amp;quot;Shampoo&amp;quot; 1)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If you look closer, you’ll notice that the word quantity is
misspelled. But the parser doesn’t have any problem with that. Such a
typo may go unnoticed for a long time and quitely affect how your
application works.&lt;/p&gt;
&lt;h3 id=&quot;error-reporting&quot;&gt;Error reporting&lt;/h3&gt;
&lt;p&gt;Let’s say I am a returning user who vaguely remembers the YAML format
for Items. I might have written something like&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb8&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb8-1&quot;&gt;&lt;a href=&quot;#cb8-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;decodeEither &lt;span class=&quot;st&quot;&gt;&amp;quot;{name: Shampoo, quantity: 2}&amp;quot;&lt;/span&gt;&lt;span class=&quot;ot&quot;&gt; ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Either&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Item&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;pre&gt;&lt;code&gt;Left &amp;quot;when expecting a string, encountered Object instead&amp;quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;“That’s weird. I could swear this app accepted some form of an object
where you could specify the quantity. But apparently I’m wrong, it only
accepts simple strings.”&lt;/p&gt;
&lt;h2 id=&quot;how-to-fix-it&quot;&gt;How to fix it&lt;/h2&gt;
&lt;h3 id=&quot;check-for-unrecognized-fields&quot;&gt;Check for unrecognized
fields&lt;/h3&gt;
&lt;p&gt;To address the first problem, we need to know the set of acceptable
keys. This set is impossible to extract from a &lt;code&gt;FromJSON&lt;/code&gt;
parser because it is buried inside an opaque function.&lt;/p&gt;
&lt;p&gt;Let’s change &lt;code&gt;parseJSON&lt;/code&gt; to have type
&lt;code&gt;FieldParser a&lt;/code&gt;, where &lt;code&gt;FieldParser&lt;/code&gt; is an
applicative functor that we’ll define shortly. The values of
&lt;code&gt;FieldParser&lt;/code&gt; can be constructed with combinators:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb10&quot;&gt;&lt;pre
class=&quot;sourceCode haskell ignore&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb10-1&quot;&gt;&lt;a href=&quot;#cb10-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;field&lt;/span&gt;
&lt;span id=&quot;cb10-2&quot;&gt;&lt;a href=&quot;#cb10-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;  ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Text&lt;/span&gt; &lt;span class=&quot;co&quot;&gt;-- ^ field name&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb10-3&quot;&gt;&lt;a href=&quot;#cb10-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Parser&lt;/span&gt; a &lt;span class=&quot;co&quot;&gt;-- ^ value parser&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb10-4&quot;&gt;&lt;a href=&quot;#cb10-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;FieldParser&lt;/span&gt; a&lt;/span&gt;
&lt;span id=&quot;cb10-5&quot;&gt;&lt;a href=&quot;#cb10-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb10-6&quot;&gt;&lt;a href=&quot;#cb10-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;optField&lt;/span&gt;
&lt;span id=&quot;cb10-7&quot;&gt;&lt;a href=&quot;#cb10-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;  ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Text&lt;/span&gt; &lt;span class=&quot;co&quot;&gt;-- ^ field name&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb10-8&quot;&gt;&lt;a href=&quot;#cb10-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Parser&lt;/span&gt; a &lt;span class=&quot;co&quot;&gt;-- ^ value parser&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb10-9&quot;&gt;&lt;a href=&quot;#cb10-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;FieldParser&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;Maybe&lt;/span&gt; a)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The combinators are analogous to the ones I described in &lt;a
href=&quot;2014-04-20-json-validation-combinators&quot;&gt;JSON validation
combinators&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;How can we implement the &lt;code&gt;FieldParser&lt;/code&gt; type? One
(“initial”) way is to use a &lt;a
href=&quot;2013-03-31-flavours-of-free-applicative-functors&quot;&gt;free applicative
functor&lt;/a&gt; and later interpret it in two ways: as a
&lt;code&gt;FromJSON&lt;/code&gt;-like parser and as a set of valid keys.&lt;/p&gt;
&lt;p&gt;But there’s another (“final”) way which is to compose the applicative
functor from components, one per required semantics. The semantics of
&lt;code&gt;FromJSON&lt;/code&gt; is given by
&lt;code&gt;ReaderT Object (Either ParseError)&lt;/code&gt;. The semantics of a set
of valid keys is given by &lt;code&gt;Constant (HashMap Text ())&lt;/code&gt;. We
take the product of these semantics to get the implementation of
&lt;code&gt;FieldParser&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb11&quot;&gt;&lt;pre
class=&quot;sourceCode haskell ignore&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb11-1&quot;&gt;&lt;a href=&quot;#cb11-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;newtype&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;FieldParser&lt;/span&gt; a &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;FieldParser&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb11-2&quot;&gt;&lt;a href=&quot;#cb11-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  (&lt;span class=&quot;dt&quot;&gt;Product&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb11-3&quot;&gt;&lt;a href=&quot;#cb11-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    (&lt;span class=&quot;dt&quot;&gt;ReaderT&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Object&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;Either&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;ParseError&lt;/span&gt;))&lt;/span&gt;
&lt;span id=&quot;cb11-4&quot;&gt;&lt;a href=&quot;#cb11-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    (&lt;span class=&quot;dt&quot;&gt;Constant&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;HashMap&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Text&lt;/span&gt; ())) a)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Here I used &lt;code&gt;HashMap Text ()&lt;/code&gt; instead of
&lt;code&gt;HashSet Text&lt;/code&gt; to be able to subtract this set from the
object (represented as &lt;code&gt;HashMap Text Value&lt;/code&gt;) later.&lt;/p&gt;
&lt;p&gt;Another benefit of this approach is that it’s no longer necessary to
give a name to the object (often called &lt;code&gt;o&lt;/code&gt;) as in the
Aeson-based parser. I’ve always found that awkward and unnecessary.&lt;/p&gt;
&lt;h3 id=&quot;improve-error-messages&quot;&gt;Improve error messages&lt;/h3&gt;
&lt;p&gt;Aeson’s approach to error messages is straightforward: it tries every
alternative in turn and, if none succeeds, it returns the last error
message.&lt;/p&gt;
&lt;p&gt;There are two approaches to get a more sophisticated error
reporting:&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;&lt;p&gt;Collect errors from all alternatives and somehow merge them. Each
error would carry its level of “matching”. An alternative that matched
the object but failed at key lookup matches better than the one that
expected a string instead of an object. Thus the error from the first
alternative would prevail. If there are multiple errors on the same
level, we should try to merge them. For instance, if we expect an object
or a string but got an array, then the error message should mention both
object and string as valid options.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Limited backtracking. This is what Parsec does. In our example,
when it was determined that the object was “at least somewhat” matched
by the first alternative, the second one would have been abandoned. This
approach is rather restrictive: if you have two alternatives each
expecting an object, the second one will never fire. The benefit of this
approach is its efficiency (sometimes real, sometimes imaginary), since
we never explore more than one alternative deeply.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;It turns out, when parsing &lt;code&gt;Value&lt;/code&gt;s, we can remove some of
the backtracking without imposing any restrictions. This is because we
can “factor out” common parser prefixes. If we have two parsers that
expect an object, this is equivalent to having a single parser expecting
an object. To see this, let’s represent a parser as a record with a
field per JSON “type”:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb12&quot;&gt;&lt;pre
class=&quot;sourceCode haskell ignore&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb12-1&quot;&gt;&lt;a href=&quot;#cb12-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Parser&lt;/span&gt; a &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Parser&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb12-2&quot;&gt;&lt;a href=&quot;#cb12-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  {&lt;span class=&quot;ot&quot;&gt; parseString ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Maybe&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;Text&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Either&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;ParseError&lt;/span&gt; a)&lt;/span&gt;
&lt;span id=&quot;cb12-3&quot;&gt;&lt;a href=&quot;#cb12-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  ,&lt;span class=&quot;ot&quot;&gt; parseArray  ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Maybe&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;Vector&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Value&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Either&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;ParseError&lt;/span&gt; a)&lt;/span&gt;
&lt;span id=&quot;cb12-4&quot;&gt;&lt;a href=&quot;#cb12-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  ,&lt;span class=&quot;ot&quot;&gt; parseObject ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Maybe&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;HashMap&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Text&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Value&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Either&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;ParseError&lt;/span&gt; a)&lt;/span&gt;
&lt;span id=&quot;cb12-5&quot;&gt;&lt;a href=&quot;#cb12-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;op&quot;&gt;...&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb12-6&quot;&gt;&lt;a href=&quot;#cb12-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  }&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Writing a function
&lt;code&gt;Parser a -&amp;gt; Parser a -&amp;gt; Parser a&lt;/code&gt; which merges
individual fields is then a simple exercise.&lt;/p&gt;
&lt;p&gt;Why is every field wrapped in &lt;code&gt;Maybe&lt;/code&gt;? How’s
&lt;code&gt;Nothing&lt;/code&gt; different from
&lt;code&gt;Just $ const $ Left &quot;...&quot;&lt;/code&gt;? This is so that we can see which
JSON types are valid and give a better error message. If we tried to
parse a JSON number as an &lt;code&gt;Item&lt;/code&gt;, the error message would say
that it expected an object or a string, because only those fields of the
parser would be &lt;code&gt;Just&lt;/code&gt; values.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;Parser&lt;/code&gt; type above can be mechanically derived from
the &lt;code&gt;Value&lt;/code&gt; datatype itself. In the actual implementation, I
use &lt;a
href=&quot;https://github.com/well-typed/generics-sop&quot;&gt;generics-sop&lt;/a&gt; with
great success to reduce the boilerplate. To give you an idea, here’s the
real definition of the &lt;code&gt;Parser&lt;/code&gt; type:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb13&quot;&gt;&lt;pre
class=&quot;sourceCode haskell ignore&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb13-1&quot;&gt;&lt;a href=&quot;#cb13-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;newtype&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;ParserComponent&lt;/span&gt; a fs &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;ParserComponent&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;Maybe&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;NP&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;I&lt;/span&gt; fs &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Either&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;ParseError&lt;/span&gt; a))&lt;/span&gt;
&lt;span id=&quot;cb13-2&quot;&gt;&lt;a href=&quot;#cb13-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;newtype&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Parser&lt;/span&gt; a &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Parser&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;NP&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;ParserComponent&lt;/span&gt; a) (&lt;span class=&quot;dt&quot;&gt;Code&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Value&lt;/span&gt;))&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;We can then apply a &lt;code&gt;Parser&lt;/code&gt; to a &lt;code&gt;Value&lt;/code&gt; using
&lt;a href=&quot;https://github.com/well-typed/generics-sop/issues/11&quot;&gt;this
function&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;example-revisited&quot;&gt;Example revisited&lt;/h2&gt;
&lt;p&gt;Here is the same &lt;code&gt;Item&lt;/code&gt; type and a combinator-based YAML
parser:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb14&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb14-1&quot;&gt;&lt;a href=&quot;#cb14-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;{-# LANGUAGE OverloadedStrings #-}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb14-2&quot;&gt;&lt;a href=&quot;#cb14-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Data.Text&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;Text&lt;/span&gt;)&lt;/span&gt;
&lt;span id=&quot;cb14-3&quot;&gt;&lt;a href=&quot;#cb14-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Data.Maybe&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb14-4&quot;&gt;&lt;a href=&quot;#cb14-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Data.Monoid&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb14-5&quot;&gt;&lt;a href=&quot;#cb14-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Data.Yaml.Combinators&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb14-6&quot;&gt;&lt;a href=&quot;#cb14-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb14-7&quot;&gt;&lt;a href=&quot;#cb14-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Item&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Item&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb14-8&quot;&gt;&lt;a href=&quot;#cb14-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;dt&quot;&gt;Text&lt;/span&gt; &lt;span class=&quot;co&quot;&gt;-- title&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb14-9&quot;&gt;&lt;a href=&quot;#cb14-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;dt&quot;&gt;Int&lt;/span&gt; &lt;span class=&quot;co&quot;&gt;-- quantity&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb14-10&quot;&gt;&lt;a href=&quot;#cb14-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;deriving&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Show&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb14-11&quot;&gt;&lt;a href=&quot;#cb14-11&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb14-12&quot;&gt;&lt;a href=&quot;#cb14-12&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;itemParser ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Parser&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Item&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb14-13&quot;&gt;&lt;a href=&quot;#cb14-13&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;itemParser&lt;/span&gt;
&lt;span id=&quot;cb14-14&quot;&gt;&lt;a href=&quot;#cb14-14&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt;  (&lt;span class=&quot;fu&quot;&gt;flip&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Item&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;&amp;lt;$&amp;gt;&lt;/span&gt; string)&lt;/span&gt;
&lt;span id=&quot;cb14-15&quot;&gt;&lt;a href=&quot;#cb14-15&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;op&quot;&gt;&amp;lt;&amp;gt;&lt;/span&gt; (object &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Item&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb14-16&quot;&gt;&lt;a href=&quot;#cb14-16&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;op&quot;&gt;&amp;lt;$&amp;gt;&lt;/span&gt; field &lt;span class=&quot;st&quot;&gt;&amp;quot;title&amp;quot;&lt;/span&gt; string&lt;/span&gt;
&lt;span id=&quot;cb14-17&quot;&gt;&lt;a href=&quot;#cb14-17&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;op&quot;&gt;&amp;lt;*&amp;gt;&lt;/span&gt; (fromMaybe &lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;&amp;lt;$&amp;gt;&lt;/span&gt; optField &lt;span class=&quot;st&quot;&gt;&amp;quot;quantity&amp;quot;&lt;/span&gt; integer))&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Let’s see now what errors it produces.&lt;/p&gt;
&lt;h3 id=&quot;validation-1&quot;&gt;Validation&lt;/h3&gt;
&lt;p&gt;The YAML with a typo in the key name no longer parses:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb15&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb15-1&quot;&gt;&lt;a href=&quot;#cb15-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;fu&quot;&gt;either&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;putStrLn&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; parse itemParser &lt;span class=&quot;st&quot;&gt;&amp;quot;{title: Shampoo, quanity: 2}&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;pre&gt;&lt;code&gt;Unexpected 

quanity: 2

as part of

quanity: 2
title: Shampoo&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;error-reporting-1&quot;&gt;Error reporting&lt;/h3&gt;
&lt;p&gt;Since we supplied an object, the parser explains what’s wrong with
that object without telling us it’d rather receive a string.&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb17&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb17-1&quot;&gt;&lt;a href=&quot;#cb17-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;fu&quot;&gt;either&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;putStrLn&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; parse itemParser &lt;span class=&quot;st&quot;&gt;&amp;quot;{name: Shampoo, quantity: 2}&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;pre&gt;&lt;code&gt;Expected field &amp;quot;title&amp;quot; as part of

quantity: 2
name: Shampoo&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;implementation&quot;&gt;Implementation&lt;/h2&gt;
&lt;p&gt;I originally implemented these combinators as an internal module
while working for &lt;a href=&quot;https://signalvine.com/&quot;&gt;Signal Vine&lt;/a&gt; in
2015. They kindly agreed to release it under the MIT instance, and I
finally did so in 2017.&lt;/p&gt;
&lt;p&gt;You can find the code packaged under the name yaml-combinators on &lt;a
href=&quot;https://hackage.haskell.org/package/yaml-combinators&quot;&gt;hackage&lt;/a&gt;
and &lt;a
href=&quot;https://github.com/UnkindPartition/yaml-combinators&quot;&gt;github&lt;/a&gt;.&lt;/p&gt;
</description>
                        <pubDate>Sun, 26 Jul 2015 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2015-07-26-better-yaml-parsing</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2015-07-26-better-yaml-parsing.html</guid>
                </item>
        
                <item>
                        <title>How Haskell handles signals</title>
                        <description>&lt;p&gt;How is it possible to write &lt;a
href=&quot;https://en.wikipedia.org/wiki/Unix_signal&quot;&gt;signal&lt;/a&gt; handlers in
GHC Haskell? After all, the &lt;a
href=&quot;http://pubs.opengroup.org/onlinepubs/9699919799/functions/V2_chap02.html#tag_15_04_03&quot;&gt;set
of system calls allowed inside signal handlers&lt;/a&gt; is rather limited. In
particular, it is very hard to do memory allocation safely inside a
signal handler; one would have to modify global data (and thus not be
reentrant), call one of the banned syscalls (&lt;code&gt;brk&lt;/code&gt;,
&lt;code&gt;sbrk&lt;/code&gt;, or &lt;code&gt;mmap&lt;/code&gt;), or both.&lt;/p&gt;
&lt;p&gt;On the other hand, we know that almost any Haskell code requires
memory allocation. So what’s the trick?&lt;/p&gt;
&lt;p&gt;The trick is that a Haskell handler is not installed as a true signal
handler. Instead, a signal is handled by a carefully crafted RTS
function &lt;code&gt;generic_handler&lt;/code&gt;
(&lt;code&gt;rts/posix/Signals.c&lt;/code&gt;). All that function does (assuming the
threaded RTS) is write the signal number and the &lt;code&gt;siginfo_t&lt;/code&gt;
structure describing the signal to a special pipe (called the control
pipe, see &lt;code&gt;GHC.Event.Control&lt;/code&gt;).&lt;/p&gt;
&lt;p&gt;The other end of this pipe is being watched by the timer manager
thread (&lt;code&gt;GHC.Event.TimerManager&lt;/code&gt;). When awaken by a signal
message from the control pipe, it looks up the handler corresponding to
the signal number and, in case it’s an action, runs it in a new Haskell
thread.&lt;/p&gt;
&lt;p&gt;The signal handlers are stored in a global array,
&lt;code&gt;signal_handlers&lt;/code&gt; (&lt;code&gt;GHC.Conc.Signal&lt;/code&gt;). When you
install a signal action in Haskell, you put a stable pointer to the
action’s code into the array cell corresponding to the signal number, so
that the timer thread could look it up later when an actual signal is
delivered.&lt;/p&gt;
&lt;p&gt;See also &lt;a
href=&quot;https://ghc.haskell.org/trac/ghc/wiki/Commentary/Rts/Signals&quot;
class=&quot;uri&quot;&gt;https://ghc.haskell.org/trac/ghc/wiki/Commentary/Rts/Signals&lt;/a&gt;.&lt;/p&gt;
</description>
                        <pubDate>Mon, 06 Jul 2015 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2015-07-06-haskell-signals</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2015-07-06-haskell-signals.html</guid>
                </item>
        
                <item>
                        <title>How to force a list</title>
                        <description>&lt;p&gt;Let’s say you need to force (evaluate) a lazy Haskell list.&lt;/p&gt;
&lt;p&gt;A long time ago, this was a common way to fight lazy I/O: you read a
&lt;code&gt;String&lt;/code&gt; and then force it. These days you can have normal
I/O with strict &lt;code&gt;Text&lt;/code&gt; or &lt;code&gt;ByteString&lt;/code&gt;
instead.&lt;/p&gt;
&lt;p&gt;Anyway, let’s say you do need to force a list. This came up in a &lt;a
href=&quot;https://github.com/UnkindPartition/lexer-applicative/pull/2#issuecomment-106225168&quot;&gt;pull
request&lt;/a&gt; for lexer-applicative. Another scenario is if you want to
evaluate a lazy &lt;code&gt;Text&lt;/code&gt; or &lt;code&gt;ByteString&lt;/code&gt; without
copying the chunks. Or, you know, for any other reason.&lt;/p&gt;
&lt;p&gt;First of all, how exactly do you want to force it? There are two
primary ways: force the spine or force the elements too. (You can’t
force the elements without forcing the spine.)&lt;/p&gt;
&lt;p&gt;Forcing the spine means forcing all cons cells without touching the
elements. One way to do that is to evaluate the length of the list, but
that feels ad-hoc because it computes the result that is not needed.
Here’s an elegant way to walk the spine:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb1&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb1-1&quot;&gt;&lt;a href=&quot;#cb1-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;forceSpine ::&lt;/span&gt; [a] &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; ()&lt;/span&gt;
&lt;span id=&quot;cb1-2&quot;&gt;&lt;a href=&quot;#cb1-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;forceSpine &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;foldr&lt;/span&gt; (&lt;span class=&quot;fu&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;id&lt;/span&gt;) ()&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;(Obviously, you need to force the resulting &lt;code&gt;()&lt;/code&gt; value, by
calling &lt;code&gt;evaluate&lt;/code&gt; or &lt;code&gt;seq&lt;/code&gt;-ing it to something
else, for any evaluation to take place.)&lt;/p&gt;
&lt;p&gt;&lt;code&gt;const id&lt;/code&gt;, also known as &lt;code&gt;flip const&lt;/code&gt;, returns
its second argument while ignoring the first. So the evaluation goes
like this:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb2&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb2-1&quot;&gt;&lt;a href=&quot;#cb2-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;forceSpine [x1, x2]&lt;/span&gt;
&lt;span id=&quot;cb2-2&quot;&gt;&lt;a href=&quot;#cb2-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;foldr&lt;/span&gt; (&lt;span class=&quot;fu&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;id&lt;/span&gt;) () [x1, x2]&lt;/span&gt;
&lt;span id=&quot;cb2-3&quot;&gt;&lt;a href=&quot;#cb2-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; (&lt;span class=&quot;fu&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;id&lt;/span&gt;) x1 &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;foldr&lt;/span&gt; (&lt;span class=&quot;fu&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;id&lt;/span&gt;) () [x2]&lt;/span&gt;
&lt;span id=&quot;cb2-4&quot;&gt;&lt;a href=&quot;#cb2-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;foldr&lt;/span&gt; (&lt;span class=&quot;fu&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;id&lt;/span&gt;) () [x2]&lt;/span&gt;
&lt;span id=&quot;cb2-5&quot;&gt;&lt;a href=&quot;#cb2-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; (&lt;span class=&quot;fu&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;id&lt;/span&gt;) x2 &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;foldr&lt;/span&gt; (&lt;span class=&quot;fu&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;id&lt;/span&gt;) () []&lt;/span&gt;
&lt;span id=&quot;cb2-6&quot;&gt;&lt;a href=&quot;#cb2-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;foldr&lt;/span&gt; (&lt;span class=&quot;fu&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;id&lt;/span&gt;) () []&lt;/span&gt;
&lt;span id=&quot;cb2-7&quot;&gt;&lt;a href=&quot;#cb2-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; ()&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;See how &lt;code&gt;forceSpine&lt;/code&gt; “unpacks” the list (thus forcing the
spine) and throws all elements away.&lt;/p&gt;
&lt;p&gt;I mentioned that you may also want to force the elements of the list,
too. Most of the time you want to deep-force them, and so you should
just &lt;code&gt;rnf&lt;/code&gt; the whole list. Even when the elements are atomic
(like &lt;code&gt;Char&lt;/code&gt; or &lt;code&gt;Int&lt;/code&gt;), evaluating them to weak
head normal form is still equivalent to &lt;code&gt;rnf&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;But occasionally you do want to shallow-force the elements. In that
case, simply replace &lt;code&gt;const id&lt;/code&gt; with &lt;code&gt;seq&lt;/code&gt; in the
definition of &lt;code&gt;forceSpine&lt;/code&gt; to obtain
&lt;code&gt;forceElements&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb3&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb3-1&quot;&gt;&lt;a href=&quot;#cb3-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;forceElements ::&lt;/span&gt; [a] &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; ()&lt;/span&gt;
&lt;span id=&quot;cb3-2&quot;&gt;&lt;a href=&quot;#cb3-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;forceElements &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;foldr&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;seq&lt;/span&gt; ()&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Again, looking at the evaluation chain helps to understand what’s
going on:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb4&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb4-1&quot;&gt;&lt;a href=&quot;#cb4-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;forceElements [x1, x2]&lt;/span&gt;
&lt;span id=&quot;cb4-2&quot;&gt;&lt;a href=&quot;#cb4-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;foldr&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;seq&lt;/span&gt; () [x1, x2]&lt;/span&gt;
&lt;span id=&quot;cb4-3&quot;&gt;&lt;a href=&quot;#cb4-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;seq&lt;/span&gt; x1 &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;foldr&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;seq&lt;/span&gt; () [x2]&lt;/span&gt;
&lt;span id=&quot;cb4-4&quot;&gt;&lt;a href=&quot;#cb4-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;foldr&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;seq&lt;/span&gt; () [x2]&lt;/span&gt;
&lt;span id=&quot;cb4-5&quot;&gt;&lt;a href=&quot;#cb4-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;seq&lt;/span&gt; x2 &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;foldr&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;seq&lt;/span&gt; () []&lt;/span&gt;
&lt;span id=&quot;cb4-6&quot;&gt;&lt;a href=&quot;#cb4-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;foldr&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;seq&lt;/span&gt; () []&lt;/span&gt;
&lt;span id=&quot;cb4-7&quot;&gt;&lt;a href=&quot;#cb4-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; ()&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Same as before, only elements get forced before being thrown
away.&lt;/p&gt;
&lt;p&gt;And here’s a table that may help you understand better the difference
between &lt;code&gt;seq&lt;/code&gt;, &lt;code&gt;forceSpine&lt;/code&gt;,
&lt;code&gt;forceElements&lt;/code&gt; and &lt;code&gt;rnf&lt;/code&gt;:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;em&gt;list&lt;/em&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;`seq` ()&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;forceSpine&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;forceElements&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;rnf&lt;/code&gt;
&lt;/td&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;[Just True]&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;()&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;()&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;()&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;()&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;[Just undefined]&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;()&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;()&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;()&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;undefined&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;[undefined]&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;()&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;()&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;undefined&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;undefined&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;True : undefined&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;()&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;undefined&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;undefined&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;undefined&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;undefined&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;undefined&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;undefined&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;undefined&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;undefined&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Since &lt;code&gt;forceSpine&lt;/code&gt; and &lt;code&gt;forceElements&lt;/code&gt; are
based on &lt;code&gt;foldr&lt;/code&gt;, they can be trivially generalized to any
&lt;code&gt;Foldable&lt;/code&gt; container, with the caveat that you should
understand how the container and its &lt;code&gt;Foldable&lt;/code&gt; instance
work. For example, &lt;code&gt;forceSpine&lt;/code&gt; is useless for
&lt;code&gt;Data.Map.Map&lt;/code&gt;, since it is already spine-strict, and
&lt;code&gt;forceElements&lt;/code&gt; for a tuple will only force its second
element.&lt;/p&gt;
</description>
                        <pubDate>Thu, 28 May 2015 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2015-05-28-force-list</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2015-05-28-force-list.html</guid>
                </item>
        
                <item>
                        <title>Announcing lambda prover</title>
                        <description>&lt;p&gt;Over the last few days I wrote &lt;a
href=&quot;https://github.com/UnkindPartition/prover&quot;&gt;prover&lt;/a&gt;, a program
that can reduce terms and prove equality in the untyped lambda
calculus.&lt;/p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;/h2&gt;
&lt;p&gt;Such a tool ought to exist, but I couldn’t find anything like
that.&lt;/p&gt;
&lt;p&gt;Occasionally I want to prove stuff, such as &lt;code&gt;Monad&lt;/code&gt; or
&lt;code&gt;Applicative&lt;/code&gt; laws for various types. Very seldom such proofs
require induction; mostly they involve simple reductions and equational
reasoning.&lt;/p&gt;
&lt;p&gt;Sometimes I specifically want to &lt;a
href=&quot;2015-02-22-examples-monads-dynamic-language&quot;&gt;do it&lt;/a&gt; in the
untyped lambda calculus just to prove a point. Other times, I’m
interested in a typed theory (say, System F as an approximation for
Haskell). Fortunately, the subject reduction property guarantees us that
the results proven in ULC will hold in System F just as well.&lt;/p&gt;
&lt;p&gt;Algebraic datatypes are more tricky. From the practical perspective,
I could add data declarations and case expressions to
&lt;code&gt;prover&lt;/code&gt;, and desugar them via the Church encoding, just like
I &lt;a href=&quot;2015-02-22-examples-monads-dynamic-language#maybe&quot;&gt;did with
Maybe&lt;/a&gt; by hand. But there’s also the theoretical side of proving that
the results about Church-encoded types translate back into the original
language. Intuitively, that should hold, but I’d appreciate links to
proper proofs if anyone is aware of them.&lt;/p&gt;
&lt;p&gt;Finally, part of the motivation was to experiment with some pieces of
Haskell tech that I don’t use in my day-to-day work and evaluate them.
This part was certainly successful; I may share some specific
impressions later. Until then, feel free to read the code; at this point
it’s not too convoluted and yet I’m sure you’ll find some interesting
bits there.&lt;/p&gt;
&lt;h2 id=&quot;demo&quot;&gt;Demo&lt;/h2&gt;
&lt;p&gt;Here is an example invocation that establishes the right identity
monad law for the reader monad:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% prover -i examples/reader.lam --equal &amp;#39;bind a return&amp;#39; a
bind a return
  {- inline bind -}
= (λb c d. c (b d) d) a return
  {- inline return -}
= (λb c d. c (b d) d) a (λb c. b)
  {- β-reduce -}
= (λb c. b (a c) c) (λb c. b)
  {- β-reduce -}
= λb. (λc d. c) (a b) b
  {- β-reduce -}
= λb. (λc. a b) b
  {- β-reduce -}
= λb. a b
  {- η-reduce -}
= a&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The file &lt;code&gt;examples/reader.lam&lt;/code&gt; (included in the
repository) contains the definitions of &lt;code&gt;return&lt;/code&gt; and
&lt;code&gt;bind&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;return = \x r. x ;
bind = \a k r. k (a r) r ;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You can also ask &lt;code&gt;prover&lt;/code&gt; to reduce an expression:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% prover -i examples/arith.lam --reduce &amp;#39;mult two three&amp;#39;            
λa b. a (a (a (a (a (a b)))))&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Files are optional; you can give an entire term on the command
line:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% prover --reduce &amp;#39;(\x. y x) (\z . z)&amp;#39;
y (λa. a)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;prover&lt;/code&gt; uses De Bruijn indices, so bound variable names
are not preserved.&lt;/p&gt;
&lt;p&gt;One thing to note is that right now &lt;code&gt;--reduce&lt;/code&gt; reports a
fixed point of the reduction pipeline and not necessarily a normal
form:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% prover --reduce &amp;#39;(\x. x x) (\x. x x)&amp;#39;
(λa. a a) (λa. a a)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If &lt;code&gt;prover&lt;/code&gt; can’t find a reduced form, it will say so:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% prover --reduce &amp;#39;(\x. x x) (\x. x x x)&amp;#39;
No reduced form found&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;prover&lt;/code&gt; has a couple of knobs for more complicated cases.
There is the number of iterations configured with &lt;code&gt;--fuel&lt;/code&gt;;
and for the &lt;code&gt;--equal&lt;/code&gt; mode there is
&lt;code&gt;--size-limit&lt;/code&gt;, which instructs the tool to ignore large
terms. E.g. this invocation completes immediately:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% prover -i examples/pair.lam -i examples/bool.lam -i examples/arith.lam --reduce &amp;#39;pred one&amp;#39; 
λa b. b&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;But in order to get a nice proof for the same reduction, you’ll need
to find the right limits and wait for about 7 seconds. You will also be
surprised how non-trivial the proof is.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% prover -i examples/pair.lam -i examples/bool.lam -i examples/arith.lam \
  --equal &amp;#39;pred one&amp;#39; zero \
  --fuel 50 --size-limit 40
pred one
  {- inline pred -}
= (λa b c. snd (a (λd. pair true (fst d b (λe. e) (snd d))) (pair false c))) one
[...]
= λa b. pair true ((λc. c (λd e. e) b) (λc d. c) a (λc. c) ((λc. c (λd e. e) b) (λc d. d))) (λc d. d)
[...]
= λa b. b

zero
  {- inline zero -}
= λa b. b&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is because &lt;code&gt;--equal&lt;/code&gt; has to consider all reduction
paths to find the minimal one, and there are too many different ways to
reduce this term.&lt;/p&gt;
&lt;p&gt;Finally, its majesty factorial:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% prover -i examples/pair.lam -i examples/bool.lam -i examples/arith.lam -i examples/fixpoint.lam \
  --fuel 20 \
  --reduce &amp;#39;fact three&amp;#39; 
λa b. a (a (a (a (a (a b)))))&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;(I didn’t manage to compute &lt;code&gt;fact four&lt;/code&gt;, though.)&lt;/p&gt;
</description>
                        <pubDate>Wed, 27 May 2015 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2015-05-27-prover</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2015-05-27-prover.html</guid>
                </item>
        
                <item>
                        <title>Smarter validation</title>
                        <description>&lt;p&gt;Today we’ll explore different ways of handling and reporting errors
in Haskell. We shall start with the well-known &lt;code&gt;Either&lt;/code&gt;
monad, proceed to a somewhat less common &lt;code&gt;Validation&lt;/code&gt;
applicative, and then improve its efficiency and user experience.&lt;/p&gt;
&lt;p&gt;The article contains several exercises that will hopefully help you
better understand the issues that are being addressed here.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;See also: &lt;a
href=&quot;/articles/2019-03-02-lazy-validation-applicative&quot;&gt;Lazy
validation&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;h2 id=&quot;running-example&quot;&gt;Running example&lt;/h2&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb1&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb1-1&quot;&gt;&lt;a href=&quot;#cb1-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;{-# LANGUAGE GeneralizedNewtypeDeriving, KindSignatures, DataKinds,&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-2&quot;&gt;&lt;a href=&quot;#cb1-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;             ScopedTypeVariables, RankNTypes, DeriveFunctor #-}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-3&quot;&gt;&lt;a href=&quot;#cb1-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Text.Printf&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-4&quot;&gt;&lt;a href=&quot;#cb1-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Text.Read&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-5&quot;&gt;&lt;a href=&quot;#cb1-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Control.Monad&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-6&quot;&gt;&lt;a href=&quot;#cb1-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Control.Applicative&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-7&quot;&gt;&lt;a href=&quot;#cb1-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Control.Applicative.Lift&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;Lift&lt;/span&gt;)&lt;/span&gt;
&lt;span id=&quot;cb1-8&quot;&gt;&lt;a href=&quot;#cb1-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Control.Arrow&lt;/span&gt; (left)&lt;/span&gt;
&lt;span id=&quot;cb1-9&quot;&gt;&lt;a href=&quot;#cb1-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Data.Functor.Constant&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;Constant&lt;/span&gt;)&lt;/span&gt;
&lt;span id=&quot;cb1-10&quot;&gt;&lt;a href=&quot;#cb1-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Data.Monoid&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-11&quot;&gt;&lt;a href=&quot;#cb1-11&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Data.Traversable&lt;/span&gt; (sequenceA)&lt;/span&gt;
&lt;span id=&quot;cb1-12&quot;&gt;&lt;a href=&quot;#cb1-12&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Data.List&lt;/span&gt; (intercalate, genericTake, genericLength)&lt;/span&gt;
&lt;span id=&quot;cb1-13&quot;&gt;&lt;a href=&quot;#cb1-13&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Data.Proxy&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-14&quot;&gt;&lt;a href=&quot;#cb1-14&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;System.Exit&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-15&quot;&gt;&lt;a href=&quot;#cb1-15&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;System.IO&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-16&quot;&gt;&lt;a href=&quot;#cb1-16&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;GHC.TypeLits&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Our running example will consist of reading a list of integer numbers
from a file, one number per line, and printing their sum.&lt;/p&gt;
&lt;p&gt;Here’s the simplest way to do this in Haskell:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb2&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb2-1&quot;&gt;&lt;a href=&quot;#cb2-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;printSum1 ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;FilePath&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;IO&lt;/span&gt; ()&lt;/span&gt;
&lt;span id=&quot;cb2-2&quot;&gt;&lt;a href=&quot;#cb2-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;printSum1 path &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;sum&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;map&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;read&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;lines&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;readFile&lt;/span&gt; path&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This code works as expected for a well-formed file; however, if a
line in the file can’t be parsed as a number, we’ll get unhelpful&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Prelude.read: no parse&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;either-monad&quot;&gt;Either monad&lt;/h2&gt;
&lt;p&gt;Let’s rewrite our function to be aware of possible errors.&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb4&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb4-1&quot;&gt;&lt;a href=&quot;#cb4-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;parseNum&lt;/span&gt;
&lt;span id=&quot;cb4-2&quot;&gt;&lt;a href=&quot;#cb4-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;  ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Int&lt;/span&gt; &lt;span class=&quot;co&quot;&gt;-- line number (for error reporting)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-3&quot;&gt;&lt;a href=&quot;#cb4-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;co&quot;&gt;-- line contents&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-4&quot;&gt;&lt;a href=&quot;#cb4-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Either&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Integer&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-5&quot;&gt;&lt;a href=&quot;#cb4-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;     &lt;span class=&quot;co&quot;&gt;-- either parsed number or error message&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-6&quot;&gt;&lt;a href=&quot;#cb4-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;parseNum ln str &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-7&quot;&gt;&lt;a href=&quot;#cb4-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;case&lt;/span&gt; readMaybe str &lt;span class=&quot;kw&quot;&gt;of&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-8&quot;&gt;&lt;a href=&quot;#cb4-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;dt&quot;&gt;Just&lt;/span&gt; num &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Right&lt;/span&gt; num&lt;/span&gt;
&lt;span id=&quot;cb4-9&quot;&gt;&lt;a href=&quot;#cb4-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;dt&quot;&gt;Nothing&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Left&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-10&quot;&gt;&lt;a href=&quot;#cb4-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      printf &lt;span class=&quot;st&quot;&gt;&amp;quot;Bad number on line %d: %s&amp;quot;&lt;/span&gt; ln str&lt;/span&gt;
&lt;span id=&quot;cb4-11&quot;&gt;&lt;a href=&quot;#cb4-11&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-12&quot;&gt;&lt;a href=&quot;#cb4-12&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;co&quot;&gt;-- Print a message and exit&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-13&quot;&gt;&lt;a href=&quot;#cb4-13&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;die ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;IO&lt;/span&gt; ()&lt;/span&gt;
&lt;span id=&quot;cb4-14&quot;&gt;&lt;a href=&quot;#cb4-14&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;die msg &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-15&quot;&gt;&lt;a href=&quot;#cb4-15&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  hPutStrLn stderr msg&lt;/span&gt;
&lt;span id=&quot;cb4-16&quot;&gt;&lt;a href=&quot;#cb4-16&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  exitFailure&lt;/span&gt;
&lt;span id=&quot;cb4-17&quot;&gt;&lt;a href=&quot;#cb4-17&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-18&quot;&gt;&lt;a href=&quot;#cb4-18&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;printSum2 ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;FilePath&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;IO&lt;/span&gt; ()&lt;/span&gt;
&lt;span id=&quot;cb4-19&quot;&gt;&lt;a href=&quot;#cb4-19&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;printSum2 path &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-20&quot;&gt;&lt;a href=&quot;#cb4-20&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;fu&quot;&gt;either&lt;/span&gt; die &lt;span class=&quot;fu&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-21&quot;&gt;&lt;a href=&quot;#cb4-21&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  liftM &lt;span class=&quot;fu&quot;&gt;sum&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-22&quot;&gt;&lt;a href=&quot;#cb4-22&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;fu&quot;&gt;sequence&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;zipWith&lt;/span&gt; parseNum [&lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;..&lt;/span&gt;] &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-23&quot;&gt;&lt;a href=&quot;#cb4-23&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;fu&quot;&gt;lines&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;readFile&lt;/span&gt; path&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now, upon reading a line that is not a number, we’d see something
like&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Bad number on line 2: foo&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is a rather standard usage of the Either monad, so I won’t get
into details here. I’ll just note that there are two ways in which this
version is different from the first one:&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;We call &lt;code&gt;readMaybe&lt;/code&gt; instead of &lt;code&gt;read&lt;/code&gt; and,
upon detecting an error, construct a helpful error message. For this
reason, we keep track of the line number.&lt;/li&gt;
&lt;li&gt;Instead of throwing a runtime exception right away (using the
&lt;code&gt;error&lt;/code&gt; function), we return a pure &lt;code&gt;Either&lt;/code&gt;
value, and then combine these &lt;code&gt;Either&lt;/code&gt;s together using the
&lt;code&gt;Moand Either&lt;/code&gt; isntance.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The two changes are independent; there’s no reason why we couldn’t
use &lt;code&gt;error&lt;/code&gt; and get the same helpful error message. The
exceptions emulated by the &lt;code&gt;Either&lt;/code&gt; monad have the same
semantics here as the runtime exceptions. The benefit of the pure
formulation is that the semantics of runtime exceptions is built-in; but
the semantics of the pure data is programmable, and we will take
advantage of this fact below.&lt;/p&gt;
&lt;h2 id=&quot;validation-applicative&quot;&gt;Validation applicative&lt;/h2&gt;
&lt;p&gt;You get a thousand-line file with numbers from your accountant. He
asks you to sum them up because his enterprise software crashes
mysteriously when trying to read it.&lt;/p&gt;
&lt;p&gt;You accept the challenge, knowing that your Haskell program won’t let
you down. The program tells you&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Bad number on line 378: 12o0&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;em&gt;— I see! Someone put o instead of zero. Let me fix it.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;You locate the line 378 in your editor and replace &lt;code&gt;12o0&lt;/code&gt;
with &lt;code&gt;1200&lt;/code&gt;. Then you save the file, exit the editor, and
re-run the program.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Bad number on line 380: 11i3&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;em&gt;— Come on! There’s another similar mistake just two lines below.
Except now 1 got replaced by i. If you told me about both errors from
the beginning, I could fix them faster!&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Indeed, there’s no reason why our program couldn’t try to parse every
line in the file and tell us about all the mistakes at once.&lt;/p&gt;
&lt;p&gt;Except now we can’t use the standard &lt;code&gt;Monad&lt;/code&gt; and
&lt;code&gt;Applicative&lt;/code&gt; instances of &lt;code&gt;Either&lt;/code&gt;. We need the
&lt;code&gt;Validation&lt;/code&gt; applicative.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;Validation&lt;/code&gt; applicative combines two Either values in
such a way that, if they are both &lt;code&gt;Left&lt;/code&gt;, their left values
are combined with a monoidal operation. (In fact, even a
&lt;code&gt;Semigroup&lt;/code&gt; would suffice.) This allows us to collect errors
from different lines.&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb8&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb8-1&quot;&gt;&lt;a href=&quot;#cb8-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;newtype&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Validation&lt;/span&gt; e a &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Validation&lt;/span&gt; {&lt;span class=&quot;ot&quot;&gt; getValidation ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Either&lt;/span&gt; e a }&lt;/span&gt;
&lt;span id=&quot;cb8-2&quot;&gt;&lt;a href=&quot;#cb8-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;deriving&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Functor&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb8-3&quot;&gt;&lt;a href=&quot;#cb8-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb8-4&quot;&gt;&lt;a href=&quot;#cb8-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;instance&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Monoid&lt;/span&gt; e &lt;span class=&quot;ot&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Applicative&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;Validation&lt;/span&gt; e) &lt;span class=&quot;kw&quot;&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb8-5&quot;&gt;&lt;a href=&quot;#cb8-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;fu&quot;&gt;pure&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Validation&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Right&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb8-6&quot;&gt;&lt;a href=&quot;#cb8-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;dt&quot;&gt;Validation&lt;/span&gt; a &lt;span class=&quot;op&quot;&gt;&amp;lt;*&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Validation&lt;/span&gt; b &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Validation&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb8-7&quot;&gt;&lt;a href=&quot;#cb8-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;kw&quot;&gt;case&lt;/span&gt; a &lt;span class=&quot;kw&quot;&gt;of&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb8-8&quot;&gt;&lt;a href=&quot;#cb8-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;dt&quot;&gt;Right&lt;/span&gt; va &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;fmap&lt;/span&gt; va b&lt;/span&gt;
&lt;span id=&quot;cb8-9&quot;&gt;&lt;a href=&quot;#cb8-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;dt&quot;&gt;Left&lt;/span&gt; ea &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;either&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;Left&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;mappend&lt;/span&gt; ea) (&lt;span class=&quot;fu&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Left&lt;/span&gt; ea) b&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The following example demonstrates the difference between the
standard &lt;code&gt;Applicative&lt;/code&gt; instance and the
&lt;code&gt;Validation&lt;/code&gt; one:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt; let e1 = Left &amp;quot;error1&amp;quot;; e2 = Left &amp;quot; error2&amp;quot;
&amp;gt; e1 *&amp;gt; e2
Left &amp;quot;error1&amp;quot;
&amp;gt; getValidation $ Validation e1 *&amp;gt; Validation e2
Left &amp;quot;error1 error2&amp;quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;A clever implementation of the same applicative functor exists inside
the transformers package. Ross Paterson observes that this functor can
be constructed as&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb10&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb10-1&quot;&gt;&lt;a href=&quot;#cb10-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Errors&lt;/span&gt; e &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Lift&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;Constant&lt;/span&gt; e)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;(see &lt;code&gt;Control.Applicative.Lift&lt;/code&gt;).&lt;/p&gt;
&lt;p&gt;Anyway, let’s use this to improve our summing program.&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb11&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb11-1&quot;&gt;&lt;a href=&quot;#cb11-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;printSum3 ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;FilePath&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;IO&lt;/span&gt; ()&lt;/span&gt;
&lt;span id=&quot;cb11-2&quot;&gt;&lt;a href=&quot;#cb11-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;printSum3 path &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb11-3&quot;&gt;&lt;a href=&quot;#cb11-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;fu&quot;&gt;either&lt;/span&gt; (die &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt; intercalate &lt;span class=&quot;st&quot;&gt;&amp;quot;\n&amp;quot;&lt;/span&gt;) &lt;span class=&quot;fu&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb11-4&quot;&gt;&lt;a href=&quot;#cb11-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  liftM &lt;span class=&quot;fu&quot;&gt;sum&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb11-5&quot;&gt;&lt;a href=&quot;#cb11-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  getValidation &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;sequenceA&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb11-6&quot;&gt;&lt;a href=&quot;#cb11-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;fu&quot;&gt;map&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;Validation&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt; left (\e &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; [e])) &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb11-7&quot;&gt;&lt;a href=&quot;#cb11-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;fu&quot;&gt;zipWith&lt;/span&gt; parseNum [&lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;..&lt;/span&gt;] &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb11-8&quot;&gt;&lt;a href=&quot;#cb11-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;fu&quot;&gt;lines&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;=&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;readFile&lt;/span&gt; path&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now a single invocation of the program shows all the errors it can
find:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Bad number on line 378: 12o0
Bad number on line 380: 11i3&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Exercise.&lt;/strong&gt; Could we use &lt;code&gt;Writer [String]&lt;/code&gt;
to collect error messages?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Exercise.&lt;/strong&gt; When appending lists, there is a danger of
incurring quadratic complexity. Does that happen in the above function?
Could it happen in a different function that uses the
&lt;code&gt;Validation&lt;/code&gt; applicative based on the list monoid?&lt;/p&gt;
&lt;h2 id=&quot;smarter-validation-applicative&quot;&gt;Smarter Validation
applicative&lt;/h2&gt;
&lt;p&gt;Next day your accountant sends you another thousand-line file to sum
up. This time your terminal gets flooded by error messages:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Bad number on line 1: 27297.
Bad number on line 2: 11986.
Bad number on line 3: 18938.
Bad number on line 4: 22820.
...&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You already see the problem: every number ends with a dot. This is
trivial to diagnose and fix, and there is absolutely no need to print a
thousand error messages.&lt;/p&gt;
&lt;p&gt;In fact, there are two different reasons to limit the number of
reported errors:&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;User experience: it is unlikely that the user will pay attention to
more than, say, 10 messages at once. If we try to display too many
errors on a web page, it may get slow and ugly.&lt;/li&gt;
&lt;li&gt;Efficiency: if we agree it’s only worth printing the first 10
errors, then, once we gather 10 errors, there is no point processing the
data further.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Turns out, each of the two goals outlined above will need its own
mechanism.&lt;/p&gt;
&lt;h3 id=&quot;bounded-lists&quot;&gt;Bounded lists&lt;/h3&gt;
&lt;p&gt;We first develop a list-like datatype which stores only the first
&lt;code&gt;n&lt;/code&gt; elements and discards anything else that may get
appended. This primarily addresses our first goal, user experience,
although it will be handy for achieving the second goal too.&lt;/p&gt;
&lt;p&gt;Although for validation purposes we may settle with the limit of 10,
it’s nice to make this a generic, reusable type with a flexible limit.
So we’ll make the limit a part of the type, taking advantage of the
type-level number literals.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Exercise.&lt;/strong&gt; Think of the alternatives to storing the
limit in the type. What are their pros and cons?&lt;/p&gt;
&lt;p&gt;On the value level, we will base the new type on difference lists, to
avoid the quadratic complexity issue that I allude to above.&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb14&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb14-1&quot;&gt;&lt;a href=&quot;#cb14-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;BoundedList&lt;/span&gt; (&lt;span class=&quot;ot&quot;&gt;n ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Nat&lt;/span&gt;) a &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb14-2&quot;&gt;&lt;a href=&quot;#cb14-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;dt&quot;&gt;BoundedList&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb14-3&quot;&gt;&lt;a href=&quot;#cb14-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;op&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;dt&quot;&gt;Integer&lt;/span&gt; &lt;span class=&quot;co&quot;&gt;-- current length of the list&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb14-4&quot;&gt;&lt;a href=&quot;#cb14-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    (&lt;span class=&quot;dt&quot;&gt;Endo&lt;/span&gt; [a])&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Exercise.&lt;/strong&gt; Why is it important to cache the current
length instead of computing it from the difference list?&lt;/p&gt;
&lt;p&gt;Once we’ve figured out the main ideas (encoding the limit in the
type, using difference lists, caching the current length), the actual
implementation is straightforward.&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb15&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb15-1&quot;&gt;&lt;a href=&quot;#cb15-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;singleton ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;KnownNat&lt;/span&gt; n &lt;span class=&quot;ot&quot;&gt;=&amp;gt;&lt;/span&gt; a &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;BoundedList&lt;/span&gt; n a&lt;/span&gt;
&lt;span id=&quot;cb15-2&quot;&gt;&lt;a href=&quot;#cb15-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;singleton a &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; fromList [a]&lt;/span&gt;
&lt;span id=&quot;cb15-3&quot;&gt;&lt;a href=&quot;#cb15-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb15-4&quot;&gt;&lt;a href=&quot;#cb15-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;toList ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;BoundedList&lt;/span&gt; n a &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; [a]&lt;/span&gt;
&lt;span id=&quot;cb15-5&quot;&gt;&lt;a href=&quot;#cb15-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;toList (&lt;span class=&quot;dt&quot;&gt;BoundedList&lt;/span&gt; _ (&lt;span class=&quot;dt&quot;&gt;Endo&lt;/span&gt; f)) &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; f []&lt;/span&gt;
&lt;span id=&quot;cb15-6&quot;&gt;&lt;a href=&quot;#cb15-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb15-7&quot;&gt;&lt;a href=&quot;#cb15-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;fromList ::&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;forall&lt;/span&gt; a n &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;KnownNat&lt;/span&gt; n &lt;span class=&quot;ot&quot;&gt;=&amp;gt;&lt;/span&gt; [a] &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;BoundedList&lt;/span&gt; n a&lt;/span&gt;
&lt;span id=&quot;cb15-8&quot;&gt;&lt;a href=&quot;#cb15-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;fromList lst &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;BoundedList&lt;/span&gt; (&lt;span class=&quot;fu&quot;&gt;min&lt;/span&gt; len limit) (&lt;span class=&quot;dt&quot;&gt;Endo&lt;/span&gt; (genericTake limit lst &lt;span class=&quot;op&quot;&gt;++&lt;/span&gt;))&lt;/span&gt;
&lt;span id=&quot;cb15-9&quot;&gt;&lt;a href=&quot;#cb15-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb15-10&quot;&gt;&lt;a href=&quot;#cb15-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    limit &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; natVal (&lt;span class=&quot;dt&quot;&gt;Proxy&lt;/span&gt;&lt;span class=&quot;ot&quot;&gt; ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Proxy&lt;/span&gt; n)&lt;/span&gt;
&lt;span id=&quot;cb15-11&quot;&gt;&lt;a href=&quot;#cb15-11&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    len &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; genericLength lst&lt;/span&gt;
&lt;span id=&quot;cb15-12&quot;&gt;&lt;a href=&quot;#cb15-12&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb15-13&quot;&gt;&lt;a href=&quot;#cb15-13&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;instance&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;KnownNat&lt;/span&gt; n &lt;span class=&quot;ot&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Monoid&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;BoundedList&lt;/span&gt; n a) &lt;span class=&quot;kw&quot;&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb15-14&quot;&gt;&lt;a href=&quot;#cb15-14&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;fu&quot;&gt;mempty&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;BoundedList&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;mempty&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb15-15&quot;&gt;&lt;a href=&quot;#cb15-15&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;fu&quot;&gt;mappend&lt;/span&gt; b1&lt;span class=&quot;op&quot;&gt;@&lt;/span&gt;(&lt;span class=&quot;dt&quot;&gt;BoundedList&lt;/span&gt; l1 f1) (&lt;span class=&quot;dt&quot;&gt;BoundedList&lt;/span&gt; l2 f2)&lt;/span&gt;
&lt;span id=&quot;cb15-16&quot;&gt;&lt;a href=&quot;#cb15-16&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;op&quot;&gt;|&lt;/span&gt; l1 &lt;span class=&quot;op&quot;&gt;&amp;gt;=&lt;/span&gt; limit &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; b1&lt;/span&gt;
&lt;span id=&quot;cb15-17&quot;&gt;&lt;a href=&quot;#cb15-17&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;op&quot;&gt;|&lt;/span&gt; l1 &lt;span class=&quot;op&quot;&gt;+&lt;/span&gt; l2 &lt;span class=&quot;op&quot;&gt;&amp;lt;=&lt;/span&gt; limit &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;BoundedList&lt;/span&gt; (l1 &lt;span class=&quot;op&quot;&gt;+&lt;/span&gt; l2) (f1 &lt;span class=&quot;op&quot;&gt;&amp;lt;&amp;gt;&lt;/span&gt; f2)&lt;/span&gt;
&lt;span id=&quot;cb15-18&quot;&gt;&lt;a href=&quot;#cb15-18&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;op&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;otherwise&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;BoundedList&lt;/span&gt; limit (f1 &lt;span class=&quot;op&quot;&gt;&amp;lt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Endo&lt;/span&gt; (genericTake (limit &lt;span class=&quot;op&quot;&gt;-&lt;/span&gt; l1)) &lt;span class=&quot;op&quot;&gt;&amp;lt;&amp;gt;&lt;/span&gt; f2)&lt;/span&gt;
&lt;span id=&quot;cb15-19&quot;&gt;&lt;a href=&quot;#cb15-19&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;kw&quot;&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb15-20&quot;&gt;&lt;a href=&quot;#cb15-20&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      limit &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; natVal (&lt;span class=&quot;dt&quot;&gt;Proxy&lt;/span&gt;&lt;span class=&quot;ot&quot;&gt; ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Proxy&lt;/span&gt; n)&lt;/span&gt;
&lt;span id=&quot;cb15-21&quot;&gt;&lt;a href=&quot;#cb15-21&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb15-22&quot;&gt;&lt;a href=&quot;#cb15-22&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;full ::&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;forall&lt;/span&gt; a n &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;KnownNat&lt;/span&gt; n &lt;span class=&quot;ot&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;BoundedList&lt;/span&gt; n a &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Bool&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb15-23&quot;&gt;&lt;a href=&quot;#cb15-23&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;full (&lt;span class=&quot;dt&quot;&gt;BoundedList&lt;/span&gt; l _) &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; l &lt;span class=&quot;op&quot;&gt;&amp;gt;=&lt;/span&gt; natVal (&lt;span class=&quot;dt&quot;&gt;Proxy&lt;/span&gt;&lt;span class=&quot;ot&quot;&gt; ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Proxy&lt;/span&gt; n)&lt;/span&gt;
&lt;span id=&quot;cb15-24&quot;&gt;&lt;a href=&quot;#cb15-24&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb15-25&quot;&gt;&lt;a href=&quot;#cb15-25&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;fu&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;ot&quot;&gt; ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;BoundedList&lt;/span&gt; n a &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Bool&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb15-26&quot;&gt;&lt;a href=&quot;#cb15-26&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;fu&quot;&gt;null&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;BoundedList&lt;/span&gt; l _) &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; l &lt;span class=&quot;op&quot;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;0&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;smartvalidation&quot;&gt;SmartValidation&lt;/h3&gt;
&lt;p&gt;Now we will build the smart validation applicative which stops doing
work when it doesn’t make sense to collect errors further anymore. This
is a balance between the &lt;code&gt;Either&lt;/code&gt; applicative, which can only
store a single error, and &lt;code&gt;Validation&lt;/code&gt;, which collects all of
them.&lt;/p&gt;
&lt;p&gt;Implementing such an applicative functor is not as trivial as it may
appear at first. In fact, before reading the code below, I recommend
doing the following&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Exercise.&lt;/strong&gt; Try implementing a type and an applicative
instance for it which adheres to the above specification.&lt;/p&gt;
&lt;p&gt;Did you try it? Did you succeed? This is not a rhetorical question, I
am actually interested, so let me know. Is your implementation the same
as mine, or is it simpler, or more complicated?&lt;/p&gt;
&lt;p&gt;Alright, here’s my implementation.&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb16&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb16-1&quot;&gt;&lt;a href=&quot;#cb16-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;newtype&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;SmartValidation&lt;/span&gt; (&lt;span class=&quot;ot&quot;&gt;n ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Nat&lt;/span&gt;) e a &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;SmartValidation&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb16-2&quot;&gt;&lt;a href=&quot;#cb16-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  {&lt;span class=&quot;ot&quot;&gt; getSmartValidation ::&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;forall&lt;/span&gt; r &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb16-3&quot;&gt;&lt;a href=&quot;#cb16-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;dt&quot;&gt;Either&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;BoundedList&lt;/span&gt; n e) (a &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; r) &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Either&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;BoundedList&lt;/span&gt; n e) r }&lt;/span&gt;
&lt;span id=&quot;cb16-4&quot;&gt;&lt;a href=&quot;#cb16-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;deriving&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Functor&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb16-5&quot;&gt;&lt;a href=&quot;#cb16-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb16-6&quot;&gt;&lt;a href=&quot;#cb16-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;instance&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;KnownNat&lt;/span&gt; n &lt;span class=&quot;ot&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Applicative&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;SmartValidation&lt;/span&gt; n e) &lt;span class=&quot;kw&quot;&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb16-7&quot;&gt;&lt;a href=&quot;#cb16-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;fu&quot;&gt;pure&lt;/span&gt; x &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;SmartValidation&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; \k &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; k &lt;span class=&quot;op&quot;&gt;&amp;lt;*&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Right&lt;/span&gt; x&lt;/span&gt;
&lt;span id=&quot;cb16-8&quot;&gt;&lt;a href=&quot;#cb16-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;dt&quot;&gt;SmartValidation&lt;/span&gt; a &lt;span class=&quot;op&quot;&gt;&amp;lt;*&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;SmartValidation&lt;/span&gt; b &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;SmartValidation&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; \k &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb16-9&quot;&gt;&lt;a href=&quot;#cb16-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;kw&quot;&gt;let&lt;/span&gt; k&amp;#39; &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;fmap&lt;/span&gt; (&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;) k &lt;span class=&quot;kw&quot;&gt;in&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb16-10&quot;&gt;&lt;a href=&quot;#cb16-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;kw&quot;&gt;case&lt;/span&gt; a k&amp;#39; &lt;span class=&quot;kw&quot;&gt;of&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb16-11&quot;&gt;&lt;a href=&quot;#cb16-11&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;dt&quot;&gt;Left&lt;/span&gt; errs &lt;span class=&quot;op&quot;&gt;|&lt;/span&gt; full errs &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Left&lt;/span&gt; errs&lt;/span&gt;
&lt;span id=&quot;cb16-12&quot;&gt;&lt;a href=&quot;#cb16-12&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      r &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; b r&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;And here are some functions to construct and analyze
&lt;code&gt;SmartValidation&lt;/code&gt; values.&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb17&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb17-1&quot;&gt;&lt;a href=&quot;#cb17-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;co&quot;&gt;-- Convert SmartValidation to Either&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb17-2&quot;&gt;&lt;a href=&quot;#cb17-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;fatal ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;SmartValidation&lt;/span&gt; n e a &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Either&lt;/span&gt; [e] a&lt;/span&gt;
&lt;span id=&quot;cb17-3&quot;&gt;&lt;a href=&quot;#cb17-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;fatal &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; left toList &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt; (&lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Right&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;id&lt;/span&gt;) &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt; getSmartValidation&lt;/span&gt;
&lt;span id=&quot;cb17-4&quot;&gt;&lt;a href=&quot;#cb17-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb17-5&quot;&gt;&lt;a href=&quot;#cb17-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;co&quot;&gt;-- Convert Either to SmartValidation&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb17-6&quot;&gt;&lt;a href=&quot;#cb17-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;nonFatal ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;KnownNat&lt;/span&gt; n &lt;span class=&quot;ot&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Either&lt;/span&gt; e a &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;SmartValidation&lt;/span&gt; n e a&lt;/span&gt;
&lt;span id=&quot;cb17-7&quot;&gt;&lt;a href=&quot;#cb17-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;nonFatal a &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;SmartValidation&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; (\k &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; k &lt;span class=&quot;op&quot;&gt;&amp;lt;+&amp;gt;&lt;/span&gt; left singleton a)&lt;/span&gt;
&lt;span id=&quot;cb17-8&quot;&gt;&lt;a href=&quot;#cb17-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb17-9&quot;&gt;&lt;a href=&quot;#cb17-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;co&quot;&gt;-- like &amp;lt;*&amp;gt;, but mappends the errors&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb17-10&quot;&gt;&lt;a href=&quot;#cb17-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;(&lt;span class=&quot;op&quot;&gt;&amp;lt;+&amp;gt;&lt;/span&gt;)&lt;/span&gt;
&lt;span id=&quot;cb17-11&quot;&gt;&lt;a href=&quot;#cb17-11&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;  ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Monoid&lt;/span&gt; e&lt;/span&gt;
&lt;span id=&quot;cb17-12&quot;&gt;&lt;a href=&quot;#cb17-12&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;ot&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Either&lt;/span&gt; e (a &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; b)&lt;/span&gt;
&lt;span id=&quot;cb17-13&quot;&gt;&lt;a href=&quot;#cb17-13&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Either&lt;/span&gt; e a&lt;/span&gt;
&lt;span id=&quot;cb17-14&quot;&gt;&lt;a href=&quot;#cb17-14&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Either&lt;/span&gt; e b&lt;/span&gt;
&lt;span id=&quot;cb17-15&quot;&gt;&lt;a href=&quot;#cb17-15&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;a &lt;span class=&quot;op&quot;&gt;&amp;lt;+&amp;gt;&lt;/span&gt; b &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;case&lt;/span&gt; (a,b) &lt;span class=&quot;kw&quot;&gt;of&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb17-16&quot;&gt;&lt;a href=&quot;#cb17-16&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  (&lt;span class=&quot;dt&quot;&gt;Right&lt;/span&gt; va, &lt;span class=&quot;dt&quot;&gt;Right&lt;/span&gt; vb) &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Right&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; va vb&lt;/span&gt;
&lt;span id=&quot;cb17-17&quot;&gt;&lt;a href=&quot;#cb17-17&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  (&lt;span class=&quot;dt&quot;&gt;Left&lt;/span&gt; e,   &lt;span class=&quot;dt&quot;&gt;Right&lt;/span&gt; _)  &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Left&lt;/span&gt; e&lt;/span&gt;
&lt;span id=&quot;cb17-18&quot;&gt;&lt;a href=&quot;#cb17-18&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  (&lt;span class=&quot;dt&quot;&gt;Right&lt;/span&gt; _,  &lt;span class=&quot;dt&quot;&gt;Left&lt;/span&gt; e)   &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Left&lt;/span&gt; e&lt;/span&gt;
&lt;span id=&quot;cb17-19&quot;&gt;&lt;a href=&quot;#cb17-19&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  (&lt;span class=&quot;dt&quot;&gt;Left&lt;/span&gt; e1,  &lt;span class=&quot;dt&quot;&gt;Left&lt;/span&gt; e2)  &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Left&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; e1 &lt;span class=&quot;op&quot;&gt;&amp;lt;&amp;gt;&lt;/span&gt; e2&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Exercise.&lt;/strong&gt; Work out what &lt;code&gt;fmap (.) k&lt;/code&gt; does
in the definition of &lt;code&gt;&amp;lt;*&amp;gt;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Exercise.&lt;/strong&gt; In the definition of
&lt;code&gt;&amp;lt;*&amp;gt;&lt;/code&gt;, should we check whether &lt;code&gt;k&lt;/code&gt; is full
before evaluating &lt;code&gt;a k&apos;&lt;/code&gt;?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Exercise.&lt;/strong&gt; We developed two mechanisms —
&lt;code&gt;BoundedList&lt;/code&gt; and &lt;code&gt;SmartValidation&lt;/code&gt;, which seem to
do about the same thing on different levels. Would any one of these two
mechanisms suffice to achieve both our goals, user experience and
efficiency, when there are many errors being reported?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Exercise.&lt;/strong&gt; If the &lt;code&gt;SmartValidation&lt;/code&gt;
applicative was based on ordinary lists instead of difference lists,
would we be less or more likely to run into the quadratic complexity
problem compared to simple &lt;code&gt;Validation&lt;/code&gt;?&lt;/p&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Although the &lt;code&gt;Validation&lt;/code&gt; applicative is known among
Haskellers, the need to limit the number of errors it produces is rarely
(if ever) discussed. Implementing an applicative functor that limits the
number of errors and avoids doing extra work is somewhat tricky. Thus, I
am happy to share my solution and curious about how other people have
dealt with this problem.&lt;/p&gt;
</description>
                        <pubDate>Sat, 02 May 2015 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2015-05-02-smarter-validation</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2015-05-02-smarter-validation.html</guid>
                </item>
        
                <item>
                        <title>Safe concurrent MySQL access in Haskell</title>
                        <description>&lt;p&gt;&lt;strong&gt;Update (2016-10-26).&lt;/strong&gt; The mysql package has got a new
maintainer, Paul Rouse. He merged my changes that address Issue 1
described below in mysql-0.1.2. The other issues are still relevant,
though.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;&lt;a href=&quot;https://hackage.haskell.org/package/mysql&quot;&gt;mysql&lt;/a&gt;, Bryan
O’Sullivan’s low-level Haskell bindings to the libmysqlclient C library,
powers a few popular high-level MySQL libraries, including mysql-simple,
persistent-mysql, snaplet-mysql-simple, and groundhog-mysql.&lt;/p&gt;
&lt;p&gt;Most users do not suspect that &lt;strong&gt;using mysql as it stands
concurrently is unsafe&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;This article describes the issues and their solutions.&lt;/p&gt;
&lt;h2 id=&quot;issue-1-unsafe-foreign-calls&quot;&gt;Issue 1: unsafe foreign calls&lt;/h2&gt;
&lt;p&gt;As of version 0.1.1.8, mysql marks many of its ffi imports as unsafe.
This is a common trick to make these calls go faster. In our case, the
problem with unsafe calls is that they block a capability (that is, an
OS thread that can execute Haskell code). This is bad for two
reasons:&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;Fewer threads executing Haskell code may result in less multicore
utilization and &lt;strong&gt;degraded overall performance&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;If all capabilities get blocked executing related MySQL statements,
they may &lt;strong&gt;deadlock&lt;/strong&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Here’s a demonstration of such a deadlock:&lt;/p&gt;
&lt;div style=&quot;font-size: smaller;&quot;&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb1&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb1-1&quot;&gt;&lt;a href=&quot;#cb1-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;{-# LANGUAGE OverloadedStrings #-}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-2&quot;&gt;&lt;a href=&quot;#cb1-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Database.MySQL.Simple&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-3&quot;&gt;&lt;a href=&quot;#cb1-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Control.Concurrent&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-4&quot;&gt;&lt;a href=&quot;#cb1-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Control.Concurrent.STM&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-5&quot;&gt;&lt;a href=&quot;#cb1-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Control.Applicative&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-6&quot;&gt;&lt;a href=&quot;#cb1-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Control.Monad&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-7&quot;&gt;&lt;a href=&quot;#cb1-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Control.Exception&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-8&quot;&gt;&lt;a href=&quot;#cb1-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-9&quot;&gt;&lt;a href=&quot;#cb1-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;main &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-10&quot;&gt;&lt;a href=&quot;#cb1-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  tv &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; atomically &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; newTVar &lt;span class=&quot;dv&quot;&gt;0&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-11&quot;&gt;&lt;a href=&quot;#cb1-11&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  withConn &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; \conn &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-12&quot;&gt;&lt;a href=&quot;#cb1-12&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;fu&quot;&gt;mapM_&lt;/span&gt; (execute_ conn)&lt;/span&gt;
&lt;span id=&quot;cb1-13&quot;&gt;&lt;a href=&quot;#cb1-13&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      [ &lt;span class=&quot;st&quot;&gt;&amp;quot;drop table if exists test&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-14&quot;&gt;&lt;a href=&quot;#cb1-14&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      , &lt;span class=&quot;st&quot;&gt;&amp;quot;create table test (x int)&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-15&quot;&gt;&lt;a href=&quot;#cb1-15&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      , &lt;span class=&quot;st&quot;&gt;&amp;quot;insert into test values (0)&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-16&quot;&gt;&lt;a href=&quot;#cb1-16&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      ]&lt;/span&gt;
&lt;span id=&quot;cb1-17&quot;&gt;&lt;a href=&quot;#cb1-17&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;/span&gt;
&lt;span id=&quot;cb1-18&quot;&gt;&lt;a href=&quot;#cb1-18&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  forM_ [&lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;..&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;2&lt;/span&gt;] &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; \n &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; forkIO &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; withConn &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; \conn &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; (&lt;span class=&quot;kw&quot;&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-19&quot;&gt;&lt;a href=&quot;#cb1-19&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    execute_ conn &lt;span class=&quot;st&quot;&gt;&amp;quot;begin&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-20&quot;&gt;&lt;a href=&quot;#cb1-20&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;fu&quot;&gt;putStrLn&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;show&lt;/span&gt; n &lt;span class=&quot;op&quot;&gt;++&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;quot; updating&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-21&quot;&gt;&lt;a href=&quot;#cb1-21&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    execute_ conn &lt;span class=&quot;st&quot;&gt;&amp;quot;update test set x = 42&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-22&quot;&gt;&lt;a href=&quot;#cb1-22&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;fu&quot;&gt;putStrLn&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;show&lt;/span&gt; n &lt;span class=&quot;op&quot;&gt;++&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;quot; waiting&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-23&quot;&gt;&lt;a href=&quot;#cb1-23&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    threadDelay (&lt;span class=&quot;dv&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;6&lt;/span&gt;)&lt;/span&gt;
&lt;span id=&quot;cb1-24&quot;&gt;&lt;a href=&quot;#cb1-24&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    execute_ conn &lt;span class=&quot;st&quot;&gt;&amp;quot;commit&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-25&quot;&gt;&lt;a href=&quot;#cb1-25&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;fu&quot;&gt;putStrLn&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;show&lt;/span&gt; n &lt;span class=&quot;op&quot;&gt;++&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;quot; committed&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-26&quot;&gt;&lt;a href=&quot;#cb1-26&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    ) &lt;span class=&quot;ot&quot;&gt;`finally`&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-27&quot;&gt;&lt;a href=&quot;#cb1-27&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    (atomically &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; modifyTVar tv (&lt;span class=&quot;op&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;))&lt;/span&gt;
&lt;span id=&quot;cb1-28&quot;&gt;&lt;a href=&quot;#cb1-28&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-29&quot;&gt;&lt;a href=&quot;#cb1-29&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  atomically &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; check &lt;span class=&quot;op&quot;&gt;=&amp;lt;&amp;lt;&lt;/span&gt; (&lt;span class=&quot;op&quot;&gt;&amp;gt;=&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;2&lt;/span&gt;) &lt;span class=&quot;op&quot;&gt;&amp;lt;$&amp;gt;&lt;/span&gt; readTVar tv&lt;/span&gt;
&lt;span id=&quot;cb1-30&quot;&gt;&lt;a href=&quot;#cb1-30&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-31&quot;&gt;&lt;a href=&quot;#cb1-31&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    withConn &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; bracket (connect defaultConnectInfo) close&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;If you run this with stock mysql-0.1.1.8, one capability
(i.e. without &lt;code&gt;+RTS -Nx&lt;/code&gt;), and either threaded or
non-threaded runtime, you’ll see:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;1 updating
1 waiting
2 updating
1 committed
test: ConnectionError {
  errFunction = &amp;quot;query&amp;quot;,
  errNumber = 1205,
  errMessage = &amp;quot;Lock wait timeout exceeded; try restarting transaction&amp;quot;}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here’s what’s going on:&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;Both threads are trying to update the same row inside their
transactions;&lt;/li&gt;
&lt;li&gt;MySQL lets the first update pass but blocks the second one until the
first update committed (or rolled back);&lt;/li&gt;
&lt;li&gt;The first transaction never gets a chance to commit, because it has
no OS threads (capabilities) to execute on. The only capability is
blocked waiting for the second UPDATE to finish.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The solution is to patch mysql to mark its ffi calls as safe (and use
the threaded runtime). Here’s what would happen:&lt;/p&gt;
&lt;ol start=&quot;3&quot;&gt;
&lt;li&gt;
To compensate for the blocked OS thread executing the second UPDATE, the
GHC runtime moves the capability to another thread (either fresh or
drawn from a pool);
&lt;/li&gt;
&lt;li&gt;
The first transaction finishes on this unblocked capability;
&lt;/li&gt;
&lt;li&gt;
MySQL then allows the second UPDATE to go through, and the second
transaction finishes as well.
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2
id=&quot;issue-2-uninitialized-thread-local-state-in-libmysqlclient&quot;&gt;Issue 2:
uninitialized thread-local state in libmysqlclient&lt;/h2&gt;
&lt;p&gt;To quote the docs:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;When you call mysql_init(), MySQL creates a thread-specific variable
for the thread that is used by the debug library (among other things).
If you call a MySQL function before the thread has called mysql_init(),
the thread does not have the necessary thread-specific variables in
place and you are likely to end up with a core dump sooner or later.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Here’s the definition of the thread-local state data structure, taken
from mariadb-10.0.17:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb3&quot;&gt;&lt;pre class=&quot;sourceCode c&quot;&gt;&lt;code class=&quot;sourceCode c&quot;&gt;&lt;span id=&quot;cb3-1&quot;&gt;&lt;a href=&quot;#cb3-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;struct&lt;/span&gt; st_my_thread_var&lt;/span&gt;
&lt;span id=&quot;cb3-2&quot;&gt;&lt;a href=&quot;#cb3-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;op&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-3&quot;&gt;&lt;a href=&quot;#cb3-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;dt&quot;&gt;int&lt;/span&gt; thr_errno&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-4&quot;&gt;&lt;a href=&quot;#cb3-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  mysql_cond_t suspend&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-5&quot;&gt;&lt;a href=&quot;#cb3-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  mysql_mutex_t mutex&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-6&quot;&gt;&lt;a href=&quot;#cb3-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  mysql_mutex_t &lt;span class=&quot;op&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;volatile&lt;/span&gt; current_mutex&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-7&quot;&gt;&lt;a href=&quot;#cb3-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  mysql_cond_t &lt;span class=&quot;op&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;volatile&lt;/span&gt; current_cond&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-8&quot;&gt;&lt;a href=&quot;#cb3-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  pthread_t pthread_self&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-9&quot;&gt;&lt;a href=&quot;#cb3-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  my_thread_id id&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-10&quot;&gt;&lt;a href=&quot;#cb3-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;dt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;volatile&lt;/span&gt; abort&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-11&quot;&gt;&lt;a href=&quot;#cb3-11&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  my_bool init&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-12&quot;&gt;&lt;a href=&quot;#cb3-12&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;struct&lt;/span&gt; st_my_thread_var &lt;span class=&quot;op&quot;&gt;*&lt;/span&gt;next&lt;span class=&quot;op&quot;&gt;,**&lt;/span&gt;prev&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-13&quot;&gt;&lt;a href=&quot;#cb3-13&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;dt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;*&lt;/span&gt;keycache_link&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-14&quot;&gt;&lt;a href=&quot;#cb3-14&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  uint  lock_type&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;co&quot;&gt;/* used by conditional release the queue */&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-15&quot;&gt;&lt;a href=&quot;#cb3-15&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;dt&quot;&gt;void&lt;/span&gt;  &lt;span class=&quot;op&quot;&gt;*&lt;/span&gt;stack_ends_here&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-16&quot;&gt;&lt;a href=&quot;#cb3-16&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  safe_mutex_t &lt;span class=&quot;op&quot;&gt;*&lt;/span&gt;mutex_in_use&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-17&quot;&gt;&lt;a href=&quot;#cb3-17&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;pp&quot;&gt;#ifndef DBUG_OFF&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-18&quot;&gt;&lt;a href=&quot;#cb3-18&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;dt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;*&lt;/span&gt;dbug&lt;span class=&quot;op&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-19&quot;&gt;&lt;a href=&quot;#cb3-19&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;dt&quot;&gt;char&lt;/span&gt; name&lt;span class=&quot;op&quot;&gt;[&lt;/span&gt;THREAD_NAME_SIZE&lt;span class=&quot;op&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;];&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-20&quot;&gt;&lt;a href=&quot;#cb3-20&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;pp&quot;&gt;#endif&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-21&quot;&gt;&lt;a href=&quot;#cb3-21&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;op&quot;&gt;};&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This data structure is used by both server and client code, although
it seems like most of these fields are used by the server, not client
(with the exception of the &lt;code&gt;dbug&lt;/code&gt; thing), which would explain
why Haskellers have gotten away with not playing by the rules so far.
However:&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;I am not an expert, and I spent just about 20 minutes grepping the
codebase. Am I sure that there’s no code path in the client that
accesses this? No.&lt;/li&gt;
&lt;li&gt;Am I going to ignore the above warning and bet the stability of my
production system on MySQL/MariaDB devs never making use of this
thread-local state? Hell no!&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;What should we do to obey the rules?&lt;/p&gt;
&lt;p&gt;First, make threads which work with MySQL &lt;em&gt;bound&lt;/em&gt;, i.e. launch
them with &lt;code&gt;forkOS&lt;/code&gt; instead of &lt;code&gt;forkIO&lt;/code&gt;. Otherwise,
even if an OS thread is initialized, the Haskell thread may be later
scheduled on a different, uninitialized OS thread.&lt;/p&gt;
&lt;p&gt;If you create a connection in a thread, use it, and dispose of it,
then using a bound thread should be enough. This is because mysql’s
&lt;code&gt;connect&lt;/code&gt; calls &lt;code&gt;mysql_init&lt;/code&gt;, which in turn calls
&lt;code&gt;mysql_thread_init&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;However, if you are using a thread pool or otherwise sharing a
connection between threads, then &lt;code&gt;connect&lt;/code&gt; may occur on a
different OS thread than a subsequent use. Under this scenario, every
thread needs to call &lt;code&gt;mysql_thread_init&lt;/code&gt; prior to other MySQL
calls.&lt;/p&gt;
&lt;h2 id=&quot;issue-3-non-thread-safe-calls&quot;&gt;Issue 3: non-thread-safe
calls&lt;/h2&gt;
&lt;p&gt;The &lt;code&gt;mysql_library_init&lt;/code&gt; function needs to be called prior
to any other MySQL calls. It only needs to be called once per process,
although it is harmless to call it more than once.&lt;/p&gt;
&lt;p&gt;It is called implicitly by &lt;code&gt;mysql_init&lt;/code&gt; (which is in turn
called by &lt;code&gt;connect&lt;/code&gt;). However, this function is documented as
not thread-safe. If you connect from two threads simultaneously, bad or
unexpected things can happen.&lt;/p&gt;
&lt;p&gt;Also, if you are calling &lt;code&gt;mysql_thread_init&lt;/code&gt; as described
above, it should be called after &lt;code&gt;mysql_library_init&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;This is why it is a good idea to call &lt;code&gt;mysql_library_init&lt;/code&gt;
in the very beginning, before you spawn any threads.&lt;/p&gt;
&lt;h2 id=&quot;using-a-connection-concurrently&quot;&gt;Using a connection
concurrently&lt;/h2&gt;
&lt;p&gt;This is not specific to the Haskell bindings, just something to be
aware of:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;You should not use the same MySQL connection simultaneously
from different threads.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;First, the docs explicitly warn you about that:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Multiple threads cannot send a query to the MySQL server at the same
time on the same connection&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;(there are some details on this in case you are interested)&lt;/p&gt;
&lt;p&gt;Second, the MySQL wire protocol is not designed to multiplex several
communication «threads» onto the same TCP connection (unlike, say,
AMQP), and trying to do so will probably confuse both the server and the
client.&lt;/p&gt;
&lt;h2 id=&quot;example&quot;&gt;Example&lt;/h2&gt;
&lt;p&gt;Here is, to the best of my knowledge, a correct example of
concurrently accessing a MySQL database. The example accepts request at
&lt;code&gt;http://localhost/key&lt;/code&gt; and looks up that key in a MySQL
table.&lt;/p&gt;
&lt;p&gt;It needs to be compiled against my &lt;a
href=&quot;https://github.com/UnkindPartition/mysql&quot;&gt;fork of mysql&lt;/a&gt;, which
has the following changes compared to 0.1.1.8:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Unsafe calls are marked as safe (the patch is due to Matthias
Hörmann);&lt;/li&gt;
&lt;li&gt;&lt;code&gt;mysql_library_init&lt;/code&gt; and &lt;code&gt;mysql_thread_init&lt;/code&gt;
are exposed under the names &lt;code&gt;initLibrary&lt;/code&gt; and
&lt;code&gt;initThread&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;(How to use a fork that is not on hackage? For example, through a &lt;a
href=&quot;https://ro-che.info/articles/2015-02-09-dealing-with-broken-packages&quot;&gt;stackage
snapshot&lt;/a&gt;.)&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb4&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb4-1&quot;&gt;&lt;a href=&quot;#cb4-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;{-# LANGUAGE OverloadedStrings, RankNTypes #-}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-2&quot;&gt;&lt;a href=&quot;#cb4-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Network.Wai&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-3&quot;&gt;&lt;a href=&quot;#cb4-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;qualified&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Network.Wai.Handler.Warp&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Warp&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-4&quot;&gt;&lt;a href=&quot;#cb4-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Network.HTTP.Types&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-5&quot;&gt;&lt;a href=&quot;#cb4-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;qualified&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Database.MySQL.Base&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;MySQL&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-6&quot;&gt;&lt;a href=&quot;#cb4-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Database.MySQL.Simple&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-7&quot;&gt;&lt;a href=&quot;#cb4-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Control.Exception&lt;/span&gt; (bracket)&lt;/span&gt;
&lt;span id=&quot;cb4-8&quot;&gt;&lt;a href=&quot;#cb4-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Control.Monad&lt;/span&gt; (void)&lt;/span&gt;
&lt;span id=&quot;cb4-9&quot;&gt;&lt;a href=&quot;#cb4-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Control.Concurrent&lt;/span&gt; (forkOS)&lt;/span&gt;
&lt;span id=&quot;cb4-10&quot;&gt;&lt;a href=&quot;#cb4-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;qualified&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Data.Text.Lazy.Encoding&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;LT&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-11&quot;&gt;&lt;a href=&quot;#cb4-11&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Data.Pool&lt;/span&gt; (createPool, destroyAllResources, withResource)&lt;/span&gt;
&lt;span id=&quot;cb4-12&quot;&gt;&lt;a href=&quot;#cb4-12&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Data.Monoid&lt;/span&gt; (mempty)&lt;/span&gt;
&lt;span id=&quot;cb4-13&quot;&gt;&lt;a href=&quot;#cb4-13&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;GHC.IO&lt;/span&gt; (unsafeUnmask)&lt;/span&gt;
&lt;span id=&quot;cb4-14&quot;&gt;&lt;a href=&quot;#cb4-14&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-15&quot;&gt;&lt;a href=&quot;#cb4-15&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;main &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-16&quot;&gt;&lt;a href=&quot;#cb4-16&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  MySQL.initLibrary&lt;/span&gt;
&lt;span id=&quot;cb4-17&quot;&gt;&lt;a href=&quot;#cb4-17&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  bracket mkPool destroyAllResources &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; \pool &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-18&quot;&gt;&lt;a href=&quot;#cb4-18&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    Warp.runSettings (Warp.setPort &lt;span class=&quot;dv&quot;&gt;8000&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt; Warp.setFork forkOSWithUnmask &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; Warp.defaultSettings) &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-19&quot;&gt;&lt;a href=&quot;#cb4-19&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      \req resp &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-20&quot;&gt;&lt;a href=&quot;#cb4-20&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;        MySQL.initThread&lt;/span&gt;
&lt;span id=&quot;cb4-21&quot;&gt;&lt;a href=&quot;#cb4-21&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;        withResource pool &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; \conn &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-22&quot;&gt;&lt;a href=&quot;#cb4-22&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;          &lt;span class=&quot;kw&quot;&gt;case&lt;/span&gt; pathInfo req &lt;span class=&quot;kw&quot;&gt;of&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-23&quot;&gt;&lt;a href=&quot;#cb4-23&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;            [key] &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-24&quot;&gt;&lt;a href=&quot;#cb4-24&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;              rs &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; query conn &lt;span class=&quot;st&quot;&gt;&amp;quot;SELECT `desc` FROM `test` WHERE `key` = ?&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-25&quot;&gt;&lt;a href=&quot;#cb4-25&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;                (&lt;span class=&quot;dt&quot;&gt;Only&lt;/span&gt; key)&lt;/span&gt;
&lt;span id=&quot;cb4-26&quot;&gt;&lt;a href=&quot;#cb4-26&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;              &lt;span class=&quot;kw&quot;&gt;case&lt;/span&gt; rs &lt;span class=&quot;kw&quot;&gt;of&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-27&quot;&gt;&lt;a href=&quot;#cb4-27&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;                &lt;span class=&quot;dt&quot;&gt;Only&lt;/span&gt; result &lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; _ &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; resp &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-28&quot;&gt;&lt;a href=&quot;#cb4-28&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;                  responseLBS&lt;/span&gt;
&lt;span id=&quot;cb4-29&quot;&gt;&lt;a href=&quot;#cb4-29&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;                    ok200&lt;/span&gt;
&lt;span id=&quot;cb4-30&quot;&gt;&lt;a href=&quot;#cb4-30&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;                    [(hContentEncoding, &lt;span class=&quot;st&quot;&gt;&amp;quot;text/plain&amp;quot;&lt;/span&gt;)]&lt;/span&gt;
&lt;span id=&quot;cb4-31&quot;&gt;&lt;a href=&quot;#cb4-31&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;                    (&lt;span class=&quot;dt&quot;&gt;LT&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;encodeUtf8 result)&lt;/span&gt;
&lt;span id=&quot;cb4-32&quot;&gt;&lt;a href=&quot;#cb4-32&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;                _ &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; resp e404&lt;/span&gt;
&lt;span id=&quot;cb4-33&quot;&gt;&lt;a href=&quot;#cb4-33&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;            _ &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; resp e404&lt;/span&gt;
&lt;span id=&quot;cb4-34&quot;&gt;&lt;a href=&quot;#cb4-34&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-35&quot;&gt;&lt;a href=&quot;#cb4-35&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-36&quot;&gt;&lt;a href=&quot;#cb4-36&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    mkPool &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; createPool (connect defaultConnectInfo) close &lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;60&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;10&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-37&quot;&gt;&lt;a href=&quot;#cb4-37&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    e404 &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; responseLBS notFound404 [] &lt;span class=&quot;fu&quot;&gt;mempty&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-38&quot;&gt;&lt;a href=&quot;#cb4-38&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;    forkOSWithUnmask ::&lt;/span&gt; ((&lt;span class=&quot;kw&quot;&gt;forall&lt;/span&gt; a &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;IO&lt;/span&gt; a &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;IO&lt;/span&gt; a) &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;IO&lt;/span&gt; ()) &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;IO&lt;/span&gt; ()&lt;/span&gt;
&lt;span id=&quot;cb4-39&quot;&gt;&lt;a href=&quot;#cb4-39&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    forkOSWithUnmask io &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; void &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; forkOS (io unsafeUnmask)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The &lt;code&gt;forkWithUnmask&lt;/code&gt; business is only an artifact of the
way warp spawns threads; normally a simple &lt;code&gt;forkOS&lt;/code&gt; would do.
On the other hand, this example shows that in the real world you
sometimes need to make an extra effort to have bound threads. Even warp
got this feature only recently.&lt;/p&gt;
&lt;p&gt;Note that this isn’t the most efficient implementation, since it
essentially uses OS threads instead of lightweight Haskell threads to
serve requests.&lt;/p&gt;
&lt;h2 id=&quot;on-destructors&quot;&gt;On destructors&lt;/h2&gt;
&lt;p&gt;The &lt;code&gt;*_init&lt;/code&gt; functions allocate memory, so there are
complementary functions, &lt;code&gt;mysql_thread_end&lt;/code&gt; and
&lt;code&gt;mysql_library_end&lt;/code&gt;, which free that library.&lt;/p&gt;
&lt;p&gt;However, you probably do not want to call them. Here’s why.&lt;/p&gt;
&lt;p&gt;Most multithreaded Haskell programs have a small numbers of OS
threads managed by the GHC runtime. These threads are also long-lived.
Trying to free the resources associated with those threads won’t give
much, and not doing so won’t do any harm.&lt;/p&gt;
&lt;p&gt;Furthermore, suppose that you still want to free the resources. When
should you do so?&lt;/p&gt;
&lt;p&gt;Naively calling &lt;code&gt;mysql_thread_end&lt;/code&gt; after serving a request
would be wrong. It is only the lightweight Haskell thread that is
finishing. The OS thread executing the Haskell thread may be executing
other Haskell threads at the same time. If you suddenly destroy MySQL’s
thread-local state, the effect on other Haskell threads would be the
same as if you didn’t call &lt;code&gt;mysql_thread_init&lt;/code&gt; in the first
place.&lt;/p&gt;
&lt;p&gt;And calling &lt;code&gt;mysql_library_end&lt;/code&gt; without
&lt;code&gt;mysql_thread_end&lt;/code&gt; makes MySQL upset when it sees that not
all threads have ended.&lt;/p&gt;
&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/bos/mysql/issues/11&quot;&gt;GitHub issue
bos/mysql#11: Address concurrency&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a
href=&quot;http://blog.melding-monads.com/2011/10/24/concurrency-and-foreign-functions-in-the-glasgow-haskell-compiler/&quot;&gt;Leon
P Smith: Concurrency And Foreign Functions In The Glasgow Haskell
Compiler&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a
href=&quot;http://blog.ezyang.com/2010/07/safety-first-ffi-and-threading/&quot;&gt;Edward
Z. Yang: Safety first: FFI and threading&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a
href=&quot;http://community.haskell.org/~simonmar/papers/conc-ffi.pdf&quot;&gt;Simon
Marlow, Simon Peyton Jones, Wolfgang Thaller: Extending the Haskell
Foreign Function Interface with Concurrency&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a
href=&quot;https://dev.mysql.com/doc/refman/5.6/en/c-api-threaded-clients.html&quot;&gt;MySQL
5.6 Reference Manual: Writing C API Threaded Client Programs&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
</description>
                        <pubDate>Fri, 17 Apr 2015 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2015-04-17-safe-concurrent-mysql-haskell</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2015-04-17-safe-concurrent-mysql-haskell.html</guid>
                </item>
        
                <item>
                        <title>Examples of monads in a dynamic language</title>
                        <description>&lt;p&gt;In &lt;a href=&quot;2012-12-26-monads-in-dynamic-languages&quot;&gt;Monads in dynamic
languages&lt;/a&gt;, I explained what the definition of a monad in a dynamic
language should be and concluded that there’s nothing precluding them
from existing. But I didn’t give an example either.&lt;/p&gt;
&lt;p&gt;So, in case you are still wondering whether non-trivial monads are
possible in a dynamic language, here you go. I’ll implement a couple of
simple monads — Reader and Maybe — with proofs.&lt;/p&gt;
&lt;p&gt;And all that will take place in the ultimate dynamic language — the
(extensional) untyped lambda calculus.&lt;/p&gt;
&lt;p&gt;The definitions of the Reader and Maybe monads are not anything
special; they are the same definitions as you would write, say, in
Haskell, except Maybe is Church-encoded.&lt;/p&gt;
&lt;p&gt;What I find fascinating about this is that despite the untyped
language, which allows more things to go wrong than a typed one, the
monad laws still hold. You can still write monadic code and reason about
it in the untyped lambda calculus in the same way as you would do in a
typed language.&lt;/p&gt;
&lt;h2 id=&quot;reader&quot;&gt;Reader&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;return x = λr.x
a &amp;gt;&amp;gt;= k  = λr.k(ar)r&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;left-identity&quot;&gt;Left identity&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;return x &amp;gt;&amp;gt;= k
  { inline return }
  = λr.x &amp;gt;&amp;gt;= k
  { inline &amp;gt;&amp;gt;= }
  = λr.k((λr.x)r)r
  { β-reduce }
  = λr.kxr
  { η-reduce }
  = kx&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;right-identity&quot;&gt;Right identity&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;a &amp;gt;&amp;gt;= return
  { inline return }
  = a &amp;gt;&amp;gt;= λx.λr.x
  { inline &amp;gt;&amp;gt;= }
  = λr.(λx.λr.x)(ar)r
  { β-reduce }
  = λr.ar
  { η-reduce }
  = a&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;associativity&quot;&gt;Associativity&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;a &amp;gt;&amp;gt;= f &amp;gt;&amp;gt;= g
  { inline 1st &amp;gt;&amp;gt;= }
  = λr.f(ar)r &amp;gt;&amp;gt;= g
  { inline 2nd &amp;gt;&amp;gt;= }
  = λr.g((λr.f(ar)r)r)r
  { β-reduce }
  = λr.g(f(ar)r)r&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;a &amp;gt;&amp;gt;= (λx. f x &amp;gt;&amp;gt;= g)
  { inline 2nd &amp;gt;&amp;gt;= }
  = a &amp;gt;&amp;gt;= λx.λr.g((fx)r)r
  { inline 1st &amp;gt;&amp;gt;= }
  = λr.(λx.λr.g(fxr)r)(ar)r
  { β-reduce }
  = λr.g(f(ar)r)r&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;maybe&quot;&gt;Maybe&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;return x = λj.λn.jx
a &amp;gt;&amp;gt;= k  = λj.λn.a(λx.kxjn)n&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;left-identity-1&quot;&gt;Left identity&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;return x &amp;gt;&amp;gt;= k
  { inline return }
  = λj.λn.jx &amp;gt;&amp;gt;= k
  { inline &amp;gt;&amp;gt;= }
  = λj.λn.(λj.λn.jx)(λx.kxjn)n
  { β-reduce }
  = λj.λn.kxjn
  { η-reduce }
  = kx&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;right-identity-1&quot;&gt;Right identity&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;a &amp;gt;&amp;gt;= return
  { inline return }
  = a &amp;gt;&amp;gt;= λx.λj.λn.jx
  { inline &amp;gt;&amp;gt;= }
  = λj.λn.a(λx.(λx.λj.λn.jx)xjn)n
  { β-reduce }
  = λj.λn.a(λx.jx)n
  { η-reduce }
  = λj.λn.ajn
  { η-reduce }
  = a&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;associativity-1&quot;&gt;Associativity&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;a &amp;gt;&amp;gt;= f &amp;gt;&amp;gt;= g
  { inline 1st &amp;gt;&amp;gt;= }
  = (λj.λn.a(λx.fxjn)n) &amp;gt;&amp;gt;= g
  { inline 2nd &amp;gt;&amp;gt;= }
  = (λj.λn.(λj.λn.a(λx.fxjn)n)(λx.gxjn)n)
  { β-reduce }
  = λj.λn.a(λx.fx(λx.gxjn)n)n&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;a &amp;gt;&amp;gt;= (λx. f x &amp;gt;&amp;gt;= g)
  { inline 2nd &amp;gt;&amp;gt;= }
  = a &amp;gt;&amp;gt;= (λx.λj.λn.fx(λx.gxjn)n)
  { inline 1st &amp;gt;&amp;gt;= }
  = λj.λn.a(λx.(λx.λj.λn.fx(λx.gxjn)n)xjn)n
  { β-reduce }
  = λj.λn.a(λx.fx(λx.gxjn)n)n&lt;/code&gt;&lt;/pre&gt;
</description>
                        <pubDate>Sun, 22 Feb 2015 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2015-02-22-examples-monads-dynamic-language</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2015-02-22-examples-monads-dynamic-language.html</guid>
                </item>
        
                <item>
                        <title>Foldable, Traversable, and parametricity</title>
                        <description>&lt;p&gt;The &lt;a
href=&quot;https://ghc.haskell.org/trac/ghc/wiki/Prelude710/FTP&quot;&gt;Foldable-Traversable
proposal&lt;/a&gt; (aka FTP) has spawned a lot of debate in the Haskell
community.&lt;/p&gt;
&lt;p&gt;Here I want to analyze the specific concern which Ben Moseley raised
in his post, &lt;a
href=&quot;http://nattermorphisms.blogspot.com/2015/02/ftp-dangers.html&quot;&gt;FTP
dangers&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Ben’s general point is that more polymorphic (specifically, ad-hoc
polymorphic, i.e. using type classes) functions are less readable and
reliable than their monomorphic counterparts.&lt;/p&gt;
&lt;p&gt;On the other hand, Tony Morris and Chris Allen argue on twitter that
polymorphic functions are more readable due to parametricity.&lt;/p&gt;
&lt;p&gt;Is that true, however? Are the ad-hoc generalized functions more
parametric than the monomorphic versions?&lt;/p&gt;
&lt;blockquote class=&quot;twitter-tweet&quot; data-conversation=&quot;none&quot; lang=&quot;en&quot;&gt;
&lt;p&gt;
&lt;a href=&quot;https://twitter.com/shebang&quot;&gt;&lt;span class=&quot;citation&quot;
data-cites=&quot;shebang&quot;&gt;@shebang&lt;/span&gt;&lt;/a&gt;
&lt;a href=&quot;https://twitter.com/dibblego&quot;&gt;&lt;span class=&quot;citation&quot;
data-cites=&quot;dibblego&quot;&gt;@dibblego&lt;/span&gt;&lt;/a&gt; is
&lt;code&gt;(a -&amp;gt; b) -&amp;gt; [a] -&amp;gt; [b]&lt;/code&gt; more parametric than
&lt;code&gt;Functor f =&amp;gt; (a -&amp;gt; b) -&amp;gt; f a -&amp;gt; f b&lt;/code&gt; ?
&lt;/p&gt;
— Je Suis Petit Gâteau (&lt;span class=&quot;citation&quot;
data-cites=&quot;bitemyapp&quot;&gt;@bitemyapp&lt;/span&gt;)
&lt;a href=&quot;https://twitter.com/bitemyapp/status/565812105643700225&quot;&gt;February
12, 2015&lt;/a&gt;
&lt;/blockquote&gt;
&lt;script async src=&quot;//platform.twitter.com/widgets.js&quot; charset=&quot;utf-8&quot;&gt;&lt;/script&gt;
&lt;p&gt;Technically, the Functor-based type is more parametric. A function
with type &lt;code&gt;(a -&amp;gt; b) -&amp;gt; [a] -&amp;gt; [b]&lt;/code&gt; is something like
&lt;code&gt;map&lt;/code&gt;, except it may drop or duplicate some elements. On the
other hand, &lt;code&gt;Functor f =&amp;gt; (a -&amp;gt; b) -&amp;gt; f a -&amp;gt; f b&lt;/code&gt;
has to be &lt;code&gt;fmap&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;But this is a trick question! The first thing we see in the code is
the function’s &lt;em&gt;name&lt;/em&gt;, not its &lt;em&gt;type&lt;/em&gt;. What carries more
information, &lt;code&gt;map&lt;/code&gt; or &lt;code&gt;fmap&lt;/code&gt;? (Assuming both come
from the current Prelude.) Certainly &lt;code&gt;map&lt;/code&gt;. When
&lt;code&gt;fmap&lt;/code&gt; is instantiated at the list type, it is nothing more
than &lt;code&gt;map&lt;/code&gt;. When we see &lt;code&gt;fmap&lt;/code&gt;, we know that it
may or may not be &lt;code&gt;map&lt;/code&gt;. When we see &lt;code&gt;map&lt;/code&gt;, we
know it is &lt;code&gt;map&lt;/code&gt; and nothing else.&lt;/p&gt;
&lt;p&gt;The paradox is that there are more functions with &lt;code&gt;map&lt;/code&gt;’s
&lt;em&gt;type&lt;/em&gt; than &lt;code&gt;fmap&lt;/code&gt;’s, but there are more functions
with &lt;code&gt;fmap&lt;/code&gt;’s &lt;em&gt;name&lt;/em&gt; than &lt;code&gt;map&lt;/code&gt;’s. Even
though &lt;code&gt;fmap&lt;/code&gt; &lt;em&gt;is&lt;/em&gt; more parametric, that doesn’t win
us much.&lt;/p&gt;
&lt;p&gt;Nevertheless, is there a benefit in using more parametric functions
in your code? No. If it were true, we’d all be pumping our code with
«parametricity» by writing &lt;code&gt;id 3&lt;/code&gt; instead of &lt;code&gt;3&lt;/code&gt;.
You can’t get more parametric than &lt;code&gt;id&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Merely &lt;em&gt;using&lt;/em&gt; parametric functions doesn’t make code better.
Parametricity may pay off when we’re &lt;em&gt;defining&lt;/em&gt; polymorphic
parametric functions in our code instead of their monomorphic
instantiations, since parametric types are more constrained and we’re
more likely to get a compile error should we do anything stupid.&lt;/p&gt;
&lt;p&gt;(It won’t necessarily pay off; the type variables and constraints do
impose a tax on types’ readability.)&lt;/p&gt;
&lt;p&gt;But if you have an existing, monomorphic piece of code that works
with lists, simply replacing &lt;code&gt;Data.List&lt;/code&gt; functions with
&lt;code&gt;Data.Foldable&lt;/code&gt; ones inside it, &lt;em&gt;ceteris paribus&lt;/em&gt;,
will not make your code any safer or more readable.&lt;/p&gt;
</description>
                        <pubDate>Thu, 12 Feb 2015 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2015-02-12-foldable-traversable-parametricity</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2015-02-12-foldable-traversable-parametricity.html</guid>
                </item>
        
                <item>
                        <title>Dealing with broken Haskell packages</title>
                        <description>&lt;p&gt;As we approach the release of GHC 7.10, there is a new wave of
Haskell packages that require &lt;a
href=&quot;https://github.com/sof/feed/pull/8&quot;&gt;trivial fixes&lt;/a&gt; to build
with the new versions of the compiler and standard libraries, but whose
authors/maintainers are not around to apply the fixes. This is
especially annoying when there is a pull request on GitHub, and all the
maintainer would have to do is to press the green Merge button, and
upload the new version on hackage.&lt;/p&gt;
&lt;p&gt;If you are a responsible maintainer and don’t want this to happen to
&lt;em&gt;your&lt;/em&gt; packages in the future, you should &lt;a
href=&quot;2014-02-08-my-haskell-will&quot;&gt;appoint backup maintainers&lt;/a&gt; for
your packages.&lt;/p&gt;
&lt;p&gt;But what if you are a user of a package that remains broken on
hackage, even though a fix is available? Here I review several ways to
deal with this problem, including the new and promising Stackage
snapshots.&lt;/p&gt;
&lt;h2 id=&quot;building-the-package-locally&quot;&gt;Building the package locally&lt;/h2&gt;
&lt;p&gt;If all you care about is to get something installed locally (be it
the broken package itself, or something that directly or indirectly
depends on it), you can install the fixed version locally.&lt;/p&gt;
&lt;h3 id=&quot;non-sandboxed-way&quot;&gt;Non-sandboxed way&lt;/h3&gt;
&lt;p&gt;Check out the repository or branch with the fix, and cabal-install
it:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% git clone -b ghc710 https://github.com/markus1189/feed.git
% cabal install ./feed&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;(I prepend &lt;code&gt;./&lt;/code&gt; to make sure cabal understands that I mean
the directory, and not the package name on hackage.)&lt;/p&gt;
&lt;h3 id=&quot;sandboxed-way&quot;&gt;Sandboxed way&lt;/h3&gt;
&lt;p&gt;If you’re installing in the sandbox, then you can use
&lt;code&gt;add-source&lt;/code&gt; (although the non-sandboxed version will work in
this case, too):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% git clone -b ghc710 https://github.com/markus1189/feed.git
% cabal sandbox add-source feed
% cabal install whatever-you-needed&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If the package &lt;code&gt;whatever-you-needed&lt;/code&gt; has &lt;code&gt;feed&lt;/code&gt;
among its transitive dependencies, cabal will automatically install it
from the add-source’d directory.&lt;/p&gt;
&lt;h3 id=&quot;limitations&quot;&gt;Limitations&lt;/h3&gt;
&lt;p&gt;This approach doesn’t work well if:&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;&lt;p&gt;You are a maintainer of a package that depends on the broken
library. It’s hard to ask your users to check out and build the fixed
version by hand.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You work on an in-house application that your coworkers should be
able to build, for the same reason.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;forking-the-package&quot;&gt;Forking the package&lt;/h2&gt;
&lt;p&gt;You cannot upload the fixed version of a package on hackage bypassing
the maintainer. However, you can upload it under a new name. This works
well if you are a maintainer of a package that &lt;em&gt;directly&lt;/em&gt; depends
on the broken package, because you can easily make your package depend
on your fork.&lt;/p&gt;
&lt;p&gt;Examples of this are tasty depending on regex-tdfa-rc (a fork of
regex-tdfa) and tasty-golden depending on temporary-rc (a fork of
temporary).&lt;/p&gt;
&lt;h3 id=&quot;limitations-1&quot;&gt;Limitations&lt;/h3&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;&lt;p&gt;This doesn’t work well if there’s a chain of dependencies leading
from your package to the broken one. You have to either persuade the
other maintainer(s) to depend on your fork or fork the entire
chain.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If the broken package becomes actively developed again, you need
to either move back to using it or backport the bugfixes from it to your
fork. (I only fork packages when I find this scenario
unlikely.)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Other packages that depend on the broken package won’t
automatically get fixed.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Some people get upset when you fork packages.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;stackage-snapshots&quot;&gt;Stackage snapshots&lt;/h2&gt;
&lt;p&gt;Instead of uploading the fixed version to hackage (which you can’t),
you can upload it to Stackage instead, by creating a custom
snapshot.&lt;/p&gt;
&lt;p&gt;The procedure is described in &lt;a
href=&quot;https://www.fpcomplete.com/blog/2014/12/experimental-packages-stackage&quot;&gt;Experimental
package releases via Stackage Server&lt;/a&gt;. You create four files:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The fixed tarball (produced by &lt;code&gt;cabal sdist&lt;/code&gt;). You
probably want to bump the package’s version, so that it doesn’t conflict
with the version already on hackage.&lt;/li&gt;
&lt;li&gt;Two text files: &lt;code&gt;desc&lt;/code&gt; and &lt;code&gt;slug&lt;/code&gt;. The first
one contains a human-readable description of the snapshot; the second
contains an id that will become part of the snapshot’s URL.&lt;/li&gt;
&lt;li&gt;A text file with the packages to be copied directly from hackage.
For the purpose of this article, you probably want to leave this file
empty. (I don’t know if it’s ok not to include it at all.)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Then you pack these four files into a tarball (that’s right, it’ll be
a tarball with a tarball inside) and &lt;a
href=&quot;http://www.stackage.org/upload&quot;&gt;upload&lt;/a&gt; to stackage (after
registering, if you haven’t registered before).&lt;/p&gt;
&lt;p&gt;The outcome will be a custom hackage-like repository which will
contain the single version of a single package — the one you’ve
uploaded. (Of course, you can include multiple packages or versions if
you like.)&lt;/p&gt;
&lt;p&gt;The Stackage website will give you the &lt;code&gt;remote-repo&lt;/code&gt; line
that you can put into your &lt;code&gt;cabal.config&lt;/code&gt; along with the
hackage or stackage repos that are already there.&lt;/p&gt;
&lt;p&gt;In contrast to building packages locally, you can easily tell your
users or coworkers to add that repo as well.&lt;/p&gt;
&lt;h3 id=&quot;limitations-2&quot;&gt;Limitations&lt;/h3&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;&lt;p&gt;If the new hackage release of the broken package will get the
same version number as your stackage version, there will be a conflict.
(I actually don’t know what happens in that case; my guess is that cabal
will silently pick one of the two available versions.)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If the package you maintain (which depends on the broken package)
is a small one, or is deep down the dependency chain, it may be hard to
tell your users to add the repository. If, on the other hand, you
maintain a major web framework or other such thing, it would probably
work.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;taking-over-a-package&quot;&gt;Taking over a package&lt;/h2&gt;
&lt;p&gt;There’s a procedure for taking over a package &lt;a
href=&quot;https://wiki.haskell.org/Taking_over_a_package&quot;&gt;described on the
wiki&lt;/a&gt;. You’ll need to contact the current maintainer; wait an
indefinite amount of time (there’s no consensus about it; estimates vary
from 2 weeks to 6-12 months); ask again on the mailing list and wait
again; finally ask Hackage admins to grant you the rights.&lt;/p&gt;
&lt;h3 id=&quot;limitations-3&quot;&gt;Limitations&lt;/h3&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;&lt;p&gt;Since this procedure takes a long time, it’s almost never
sufficient by itself, and you’ll need to resort to one of the other
strategies until you’re given the upload rights.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;It’s not clear how long you actually need to wait.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;I find it odd that you need to jump through all these hoops in
order to do a service to the community.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
</description>
                        <pubDate>Mon, 09 Feb 2015 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2015-02-09-dealing-with-broken-packages</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2015-02-09-dealing-with-broken-packages.html</guid>
                </item>
        
                <item>
                        <title>Spiral similarity solves an IMO problem</title>
                        <description>&lt;p&gt;While recovering from a knee surgery, I entertained myself by solving
a geometry problem from the last &lt;a
href=&quot;https://www.imo-official.org/problems.aspx&quot;&gt;International
Mathematical Olympiad&lt;/a&gt;. My solution, shown below, is an example of
using plane transformations (spiral similarity, in this case) to prove
geometric statements.&lt;/p&gt;
&lt;div style=&quot;float: right;&quot;&gt;
&lt;p&gt;&lt;img src=&quot;/img/imo2014-4-problem.svg&quot; style=&quot;height: 300px;&quot;&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;h2 id=&quot;problem&quot;&gt;Problem&lt;/h2&gt;
&lt;p&gt;&lt;em&gt;(IMO-2014, P4)&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Points &lt;span class=&quot;math inline&quot;&gt;\(P\)&lt;/span&gt; and &lt;span
class=&quot;math inline&quot;&gt;\(Q\)&lt;/span&gt; lie on side &lt;span
class=&quot;math inline&quot;&gt;\(BC\)&lt;/span&gt; of acute-angled triangle &lt;span
class=&quot;math inline&quot;&gt;\(ABC\)&lt;/span&gt; such that &lt;span
class=&quot;math inline&quot;&gt;\(\angle PAB=\angle BCA\)&lt;/span&gt; and &lt;span
class=&quot;math inline&quot;&gt;\(\angle CAQ = \angle ABC\)&lt;/span&gt;. Points &lt;span
class=&quot;math inline&quot;&gt;\(M\)&lt;/span&gt; and &lt;span
class=&quot;math inline&quot;&gt;\(N\)&lt;/span&gt; lie on lines &lt;span
class=&quot;math inline&quot;&gt;\(AP\)&lt;/span&gt; and &lt;span
class=&quot;math inline&quot;&gt;\(AQ\)&lt;/span&gt;, respectively, such that &lt;span
class=&quot;math inline&quot;&gt;\(P\)&lt;/span&gt; is the midpoint of &lt;span
class=&quot;math inline&quot;&gt;\(AM\)&lt;/span&gt; and &lt;span
class=&quot;math inline&quot;&gt;\(Q\)&lt;/span&gt; is the midpoint of &lt;span
class=&quot;math inline&quot;&gt;\(AN\)&lt;/span&gt;. Prove that the lines &lt;span
class=&quot;math inline&quot;&gt;\(BM\)&lt;/span&gt; and &lt;span
class=&quot;math inline&quot;&gt;\(CN\)&lt;/span&gt; intersect on the circumcircle of
triangle &lt;span class=&quot;math inline&quot;&gt;\(ABC\)&lt;/span&gt;.&lt;/p&gt;
&lt;h2 id=&quot;solution&quot;&gt;Solution&lt;/h2&gt;
&lt;p&gt;Let &lt;span class=&quot;math inline&quot;&gt;\(\angle BAC = \alpha\)&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;math display&quot;&gt;\[\angle APB = \pi - \angle PAB - \angle
PBA = \pi - \angle ACB - \angle CBA =
\alpha\]&lt;/span&gt;&lt;/p&gt;
&lt;div style=&quot;float: left;&quot;&gt;
&lt;p&gt;&lt;img src=&quot;/img/imo2014-4-solution.svg&quot; style=&quot;width: 500px;&quot;&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Let &lt;span class=&quot;math inline&quot;&gt;\(B_1\)&lt;/span&gt; and &lt;span
class=&quot;math inline&quot;&gt;\(C_1\)&lt;/span&gt; be such points that &lt;span
class=&quot;math inline&quot;&gt;\(B\)&lt;/span&gt; and &lt;span
class=&quot;math inline&quot;&gt;\(C\)&lt;/span&gt; are midpoints of &lt;span
class=&quot;math inline&quot;&gt;\(AB_1\)&lt;/span&gt; and &lt;span
class=&quot;math inline&quot;&gt;\(AC_1\)&lt;/span&gt;, respectively.&lt;/p&gt;
&lt;p&gt;Consider a spiral similarity &lt;span class=&quot;math inline&quot;&gt;\(h\)&lt;/span&gt;
such that &lt;span class=&quot;math inline&quot;&gt;\(h(B_1)=A\)&lt;/span&gt; and &lt;span
class=&quot;math inline&quot;&gt;\(h(B)=C\)&lt;/span&gt; (it &lt;a
href=&quot;http://yufeizhao.com/olympiad/three_geometry_lemmas.pdf&quot;&gt;necessarily
exists&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;Now we shall prove that &lt;span class=&quot;math inline&quot;&gt;\(h(M)=N\)&lt;/span&gt;,
i.e. that &lt;span class=&quot;math inline&quot;&gt;\(h\)&lt;/span&gt; transforms the green
&lt;span style=&quot;color:#6B972D&quot;&gt; &lt;span class=&quot;math inline&quot;&gt;\(\triangle
B_1BM\)&lt;/span&gt; &lt;/span&gt; into the magenta &lt;span style=&quot;color:#922942&quot;&gt;
&lt;span class=&quot;math inline&quot;&gt;\(\triangle ACN\)&lt;/span&gt; &lt;/span&gt; .&lt;/p&gt;
&lt;p&gt;Being a spiral similarity, &lt;span class=&quot;math inline&quot;&gt;\(h\)&lt;/span&gt;
rotates all lines by the same angle. It maps &lt;span
class=&quot;math inline&quot;&gt;\(B_1B\)&lt;/span&gt; to &lt;span
class=&quot;math inline&quot;&gt;\(AC\)&lt;/span&gt;, therefore that angle equals &lt;span
class=&quot;math inline&quot;&gt;\(\angle(B_1B, AC)=\pi-\alpha\)&lt;/span&gt;. (We need to
be careful to measure all rotations in the same direction; on my drawing
it is clockwise.)&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;math inline&quot;&gt;\(h(A)=C_1\)&lt;/span&gt;, since &lt;span
class=&quot;math inline&quot;&gt;\(h\)&lt;/span&gt; preserves length ratios. So &lt;span
class=&quot;math inline&quot;&gt;\(h(AM)\)&lt;/span&gt; (where &lt;span
class=&quot;math inline&quot;&gt;\(AM\)&lt;/span&gt; denotes the line, not the segment) is
a line that passes through &lt;span
class=&quot;math inline&quot;&gt;\(h(A)=C_1\)&lt;/span&gt;. It also needs to be parallel to
&lt;span class=&quot;math inline&quot;&gt;\(BC\)&lt;/span&gt;, because &lt;span
class=&quot;math inline&quot;&gt;\(\angle (AM,BC)=\pi-\alpha\)&lt;/span&gt; is the rotation
angle of &lt;span class=&quot;math inline&quot;&gt;\(h\)&lt;/span&gt;. &lt;span
class=&quot;math inline&quot;&gt;\(C_1B_1\)&lt;/span&gt; is the unique such line (&lt;span
class=&quot;math inline&quot;&gt;\(C_1B_1 \parallel BC\)&lt;/span&gt; by the midline
theorem).&lt;/p&gt;
&lt;p&gt;Since &lt;span class=&quot;math inline&quot;&gt;\(h(AM)=C_1B_1\)&lt;/span&gt; and &lt;span
class=&quot;math inline&quot;&gt;\(h(MB_1)=NA\)&lt;/span&gt;, &lt;span
class=&quot;math display&quot;&gt;\[h(M)=h(AM\cap MB_1)=h(AM)\cap h(MB_1)=C_1B_1\cap
NA=N.\]&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Now that we know that &lt;span class=&quot;math inline&quot;&gt;\(h(BM)=CN\)&lt;/span&gt;,
we can deduce that &lt;span class=&quot;math inline&quot;&gt;\(\angle
BZC=\angle(BM,CN)=\pi-\alpha\)&lt;/span&gt; (the rotation angle). And because
&lt;span class=&quot;math inline&quot;&gt;\(\angle BAC+\angle BZC=\pi\)&lt;/span&gt;, &lt;span
class=&quot;math inline&quot;&gt;\(Z\)&lt;/span&gt; lies on the circumcircle of &lt;span
class=&quot;math inline&quot;&gt;\(ABC\)&lt;/span&gt;.&lt;/p&gt;
</description>
                        <pubDate>Sat, 31 Jan 2015 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2015-01-31-imo-2014-4</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2015-01-31-imo-2014-4.html</guid>
                </item>
        
                <item>
                        <title>Recognizing lists</title>
                        <description>&lt;div class=&quot;sourceCode&quot; id=&quot;cb1&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb1-1&quot;&gt;&lt;a href=&quot;#cb1-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Data.Monoid&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-2&quot;&gt;&lt;a href=&quot;#cb1-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Data.List&lt;/span&gt; (isSuffixOf)&lt;/span&gt;
&lt;span id=&quot;cb1-3&quot;&gt;&lt;a href=&quot;#cb1-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Control.Applicative&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-4&quot;&gt;&lt;a href=&quot;#cb1-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Control.Applicative.Permutation&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Perm&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-5&quot;&gt;&lt;a href=&quot;#cb1-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Control.Monad.Trans.State&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;You are given the following Haskell data type:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb2&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb2-1&quot;&gt;&lt;a href=&quot;#cb2-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;T&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;A&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Int&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;B&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;String&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Your task is to write a function&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb3&quot;&gt;&lt;pre
class=&quot;sourceCode haskell ignore&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb3-1&quot;&gt;&lt;a href=&quot;#cb3-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;recognize ::&lt;/span&gt; [&lt;span class=&quot;dt&quot;&gt;T&lt;/span&gt;] &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Bool&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;that would accept a list iff it contains exactly three elements, of
which:&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;one is an &lt;code&gt;A&lt;/code&gt; with a value between 3 and 7&lt;/li&gt;
&lt;li&gt;one is an &lt;code&gt;A&lt;/code&gt; with an even value&lt;/li&gt;
&lt;li&gt;one is a &lt;code&gt;B&lt;/code&gt; with a value ending in &lt;code&gt;.hs&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The &lt;code&gt;A&lt;/code&gt; elements mentioned in conditions (1) and (2) have
to be distinct, so &lt;code&gt;[A 4, A 17, B &quot;Prelude.hs&quot;]&lt;/code&gt; should not
be accepted, even though &lt;code&gt;A 4&lt;/code&gt; satisfies both (1) and
(2).&lt;/p&gt;
&lt;p&gt;This problem often arises in blackbox testing. You do something to a
system; you wait for some time while gathering all events that the
system generates. Then you want to check that the system generated all
the events it had to generate, and no extra ones. However, the order of
events may be non-deterministic. If the system concurrently makes a web
request, updates a database and sends a message to a message bus, the
order in which these events will be observed by your test suite is
arbitrary.&lt;/p&gt;
&lt;p&gt;A similar problem arises in &lt;a
href=&quot;2014-04-20-json-validation-combinators&quot;&gt;input validation&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;interface&quot;&gt;Interface&lt;/h2&gt;
&lt;p&gt;We want to solve this problem in a general and scalable way. What
would an interface to such solution look like? There are two principal
options.&lt;/p&gt;
&lt;p&gt;One is a simple function&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb4&quot;&gt;&lt;pre
class=&quot;sourceCode haskell ignore&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb4-1&quot;&gt;&lt;a href=&quot;#cb4-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;recognize ::&lt;/span&gt; [t &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Bool&lt;/span&gt;] &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; [t] &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Bool&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;that takes individual predicates and combines them into a
recognizer.&lt;/p&gt;
&lt;p&gt;Another is to split the process into the &lt;em&gt;build&lt;/em&gt; and
&lt;em&gt;use&lt;/em&gt; phases by the means of an intermediate data type:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb5&quot;&gt;&lt;pre
class=&quot;sourceCode haskell ignore&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb5-1&quot;&gt;&lt;a href=&quot;#cb5-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Parser&lt;/span&gt; t&lt;/span&gt;
&lt;span id=&quot;cb5-2&quot;&gt;&lt;a href=&quot;#cb5-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;instance&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Monoid&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Parser&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-3&quot;&gt;&lt;a href=&quot;#cb5-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-4&quot;&gt;&lt;a href=&quot;#cb5-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;toParser ::&lt;/span&gt; (t &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Bool&lt;/span&gt;) &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Parser&lt;/span&gt; t&lt;/span&gt;
&lt;span id=&quot;cb5-5&quot;&gt;&lt;a href=&quot;#cb5-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;runParser ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Parser&lt;/span&gt; t &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; [t] &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Bool&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;In this approach, you convert individual recognizers to monoidal
values, combine those values and extract the result.&lt;/p&gt;
&lt;p&gt;Semantically, the two are equivalent: if you have one of these
interfaces available, you can implement the other one. In a way, this is
a consequence of lists being the free monoid, but writing this down
explicitly is a good exercise nevertheless.&lt;/p&gt;
&lt;p&gt;The advantages of a &lt;em&gt;build-use&lt;/em&gt; interface are:&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;When the cost of the &lt;em&gt;build&lt;/em&gt; phase is non-trivial, it can be
amortized over multiple uses and/or incremental builds. (This won’t be
the case here.)&lt;/li&gt;
&lt;li&gt;The use of a specialized type is generally good for the type system
hygiene.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;We’ll start with the &lt;em&gt;build-use&lt;/em&gt; interface because I find it
more instructive.&lt;/p&gt;
&lt;h2 id=&quot;the-parser&quot;&gt;The Parser&lt;/h2&gt;
&lt;p&gt;To build the monoidal parser, we’ll use the &lt;a
href=&quot;https://hackage.haskell.org/package/action-permutations&quot;&gt;action-permutations&lt;/a&gt;
library. You may remember it from the article on &lt;a
href=&quot;2014-04-20-json-validation-combinators#objects&quot;&gt;JSON
parsing&lt;/a&gt;.&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb6&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb6-1&quot;&gt;&lt;a href=&quot;#cb6-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;newtype&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Parser&lt;/span&gt; t &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Parser&lt;/span&gt; {&lt;span class=&quot;ot&quot;&gt; getParser ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Perms&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;StateT&lt;/span&gt; [t] &lt;span class=&quot;dt&quot;&gt;Maybe&lt;/span&gt;) () }&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;StateT [t] Maybe a&lt;/code&gt; is the familiar type of parser
combinators, &lt;code&gt;[t] -&amp;gt; Maybe (a, [t])&lt;/code&gt;, that return the
left-over input. We wrap it in &lt;code&gt;Perms&lt;/code&gt; to achieve the order
independence, and then newtype it to convert its Applicative instance to
a Monoid one:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb7&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb7-1&quot;&gt;&lt;a href=&quot;#cb7-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;instance&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Monoid&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;Parser&lt;/span&gt; t) &lt;span class=&quot;kw&quot;&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb7-2&quot;&gt;&lt;a href=&quot;#cb7-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;fu&quot;&gt;mempty&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Parser&lt;/span&gt; (&lt;span class=&quot;fu&quot;&gt;pure&lt;/span&gt; ())&lt;/span&gt;
&lt;span id=&quot;cb7-3&quot;&gt;&lt;a href=&quot;#cb7-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;fu&quot;&gt;mappend&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;Parser&lt;/span&gt; a) (&lt;span class=&quot;dt&quot;&gt;Parser&lt;/span&gt; b) &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Parser&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; a &lt;span class=&quot;op&quot;&gt;*&amp;gt;&lt;/span&gt; b&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The build and use functions are straightforward:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb8&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb8-1&quot;&gt;&lt;a href=&quot;#cb8-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;toParser ::&lt;/span&gt; (t &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Bool&lt;/span&gt;) &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Parser&lt;/span&gt; t&lt;/span&gt;
&lt;span id=&quot;cb8-2&quot;&gt;&lt;a href=&quot;#cb8-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;toParser isX &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Parser&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; Perm.atom &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;StateT&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; \ts &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb8-3&quot;&gt;&lt;a href=&quot;#cb8-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;case&lt;/span&gt; ts &lt;span class=&quot;kw&quot;&gt;of&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb8-4&quot;&gt;&lt;a href=&quot;#cb8-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    (t&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt;ts&amp;#39;) &lt;span class=&quot;op&quot;&gt;|&lt;/span&gt; isX t &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Just&lt;/span&gt; ((), ts&amp;#39;)&lt;/span&gt;
&lt;span id=&quot;cb8-5&quot;&gt;&lt;a href=&quot;#cb8-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    _ &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Nothing&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb8-6&quot;&gt;&lt;a href=&quot;#cb8-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb8-7&quot;&gt;&lt;a href=&quot;#cb8-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;runParser ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Parser&lt;/span&gt; t &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; [t] &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Bool&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb8-8&quot;&gt;&lt;a href=&quot;#cb8-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;runParser p ts &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb8-9&quot;&gt;&lt;a href=&quot;#cb8-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;case&lt;/span&gt; (&lt;span class=&quot;fu&quot;&gt;flip&lt;/span&gt; execStateT ts &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt; runPerms &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt; getParser) p &lt;span class=&quot;kw&quot;&gt;of&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb8-10&quot;&gt;&lt;a href=&quot;#cb8-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;dt&quot;&gt;Just&lt;/span&gt; [] &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;True&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb8-11&quot;&gt;&lt;a href=&quot;#cb8-11&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    _ &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;False&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;usage&quot;&gt;Usage&lt;/h2&gt;
&lt;p&gt;First, let’s express our conditions in Haskell code.&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb9&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb9-1&quot;&gt;&lt;a href=&quot;#cb9-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;isA1, isA2,&lt;span class=&quot;ot&quot;&gt; isB ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;T&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Bool&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb9-2&quot;&gt;&lt;a href=&quot;#cb9-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb9-3&quot;&gt;&lt;a href=&quot;#cb9-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;isA1 x&lt;/span&gt;
&lt;span id=&quot;cb9-4&quot;&gt;&lt;a href=&quot;#cb9-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;op&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;A&lt;/span&gt; n &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; x, &lt;span class=&quot;dv&quot;&gt;3&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;&amp;lt;=&lt;/span&gt; n, n &lt;span class=&quot;op&quot;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;7&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;True&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb9-5&quot;&gt;&lt;a href=&quot;#cb9-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;op&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;otherwise&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;False&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb9-6&quot;&gt;&lt;a href=&quot;#cb9-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb9-7&quot;&gt;&lt;a href=&quot;#cb9-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;isA2 x&lt;/span&gt;
&lt;span id=&quot;cb9-8&quot;&gt;&lt;a href=&quot;#cb9-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;op&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;A&lt;/span&gt; n &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; x, &lt;span class=&quot;fu&quot;&gt;even&lt;/span&gt; n &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;True&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb9-9&quot;&gt;&lt;a href=&quot;#cb9-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;op&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;otherwise&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;False&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb9-10&quot;&gt;&lt;a href=&quot;#cb9-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb9-11&quot;&gt;&lt;a href=&quot;#cb9-11&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;isB x&lt;/span&gt;
&lt;span id=&quot;cb9-12&quot;&gt;&lt;a href=&quot;#cb9-12&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;op&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;B&lt;/span&gt; s &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; x, &lt;span class=&quot;st&quot;&gt;&amp;quot;.hs&amp;quot;&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;`isSuffixOf`&lt;/span&gt; s &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;True&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb9-13&quot;&gt;&lt;a href=&quot;#cb9-13&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;op&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;otherwise&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;False&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Combine them together:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb10&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb10-1&quot;&gt;&lt;a href=&quot;#cb10-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;parser ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Parser&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;T&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb10-2&quot;&gt;&lt;a href=&quot;#cb10-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;parser &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; (&lt;span class=&quot;fu&quot;&gt;mconcat&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;map&lt;/span&gt; toParser) [isA1, isA2, isB]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;(we could replace &lt;code&gt;mconcat . map toParser&lt;/code&gt; with
&lt;code&gt;foldMap toParser&lt;/code&gt; from &lt;code&gt;Data.Foldable&lt;/code&gt;)&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb11&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb11-1&quot;&gt;&lt;a href=&quot;#cb11-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;recognize ::&lt;/span&gt; [&lt;span class=&quot;dt&quot;&gt;T&lt;/span&gt;] &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Bool&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb11-2&quot;&gt;&lt;a href=&quot;#cb11-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;recognize &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; runParser parser&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now try it out:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb12&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb12-1&quot;&gt;&lt;a href=&quot;#cb12-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;ex1 &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; recognize [&lt;span class=&quot;dt&quot;&gt;A&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;4&lt;/span&gt;, &lt;span class=&quot;dt&quot;&gt;A&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;17&lt;/span&gt;, &lt;span class=&quot;dt&quot;&gt;B&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;quot;Prelude.hs&amp;quot;&lt;/span&gt;]&lt;/span&gt;
&lt;span id=&quot;cb12-2&quot;&gt;&lt;a href=&quot;#cb12-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;co&quot;&gt;-- =&amp;gt; False&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb12-3&quot;&gt;&lt;a href=&quot;#cb12-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;ex2 &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; recognize [&lt;span class=&quot;dt&quot;&gt;A&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;4&lt;/span&gt;, &lt;span class=&quot;dt&quot;&gt;A&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;18&lt;/span&gt;, &lt;span class=&quot;dt&quot;&gt;B&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;quot;Prelude.hs&amp;quot;&lt;/span&gt;]&lt;/span&gt;
&lt;span id=&quot;cb12-4&quot;&gt;&lt;a href=&quot;#cb12-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;co&quot;&gt;-- =&amp;gt; True&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb12-5&quot;&gt;&lt;a href=&quot;#cb12-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;ex3 &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; recognize [&lt;span class=&quot;dt&quot;&gt;B&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;quot;Prelude.hs&amp;quot;&lt;/span&gt;, &lt;span class=&quot;dt&quot;&gt;A&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;18&lt;/span&gt;, &lt;span class=&quot;dt&quot;&gt;A&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;4&lt;/span&gt;]&lt;/span&gt;
&lt;span id=&quot;cb12-6&quot;&gt;&lt;a href=&quot;#cb12-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;co&quot;&gt;-- =&amp;gt; True&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb12-7&quot;&gt;&lt;a href=&quot;#cb12-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;ex4 &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; recognize [&lt;span class=&quot;dt&quot;&gt;B&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;quot;Prelude.hs&amp;quot;&lt;/span&gt;, &lt;span class=&quot;dt&quot;&gt;A&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;18&lt;/span&gt;, &lt;span class=&quot;dt&quot;&gt;A&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;4&lt;/span&gt;, &lt;span class=&quot;dt&quot;&gt;A&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;]&lt;/span&gt;
&lt;span id=&quot;cb12-8&quot;&gt;&lt;a href=&quot;#cb12-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;co&quot;&gt;-- =&amp;gt; False&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
</description>
                        <pubDate>Thu, 29 Jan 2015 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2015-01-29-recognizing-lists</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2015-01-29-recognizing-lists.html</guid>
                </item>
        
                <item>
                        <title>Lexical analysis with parser combinators</title>
                        <description>&lt;p&gt;When writing a programming language parser in Haskell, the usual
dilemma is whether to use lexer/parser generators (Alex+Happy), or make
a single parser (using a parser combinator library like Parsec) without
an explicit tokenizer.&lt;/p&gt;
&lt;p&gt;In this article, I’ll explain why you may want to use a separate
lexer built with applicative parser combinators, and how you might go
about writing one.&lt;/p&gt;
&lt;p&gt;Many of the ideas described in this article have been since
implemented in &lt;a
href=&quot;https://hackage.haskell.org/package/lexer-applicative&quot;&gt;lexer-applicative&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;alex&quot;&gt;Alex&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://www.haskell.org/alex/&quot;&gt;Alex&lt;/a&gt;, the Haskell lexer
generator, is a nice tool, but it has a weakness. With Alex, you cannot
observe the internal structure of a token.&lt;/p&gt;
&lt;p&gt;The most common instance of this problem is parsing string
interpolation, think &lt;code&gt;&quot;Hello, ${name}!&quot;&lt;/code&gt;. Such a string is a
single token, yet it has some internal structure to it. To analyze this
with Alex, you’ll probably need to have two different lexers, and run
one inside the other.&lt;/p&gt;
&lt;p&gt;Another instance is date literals (useful for many DSLs), such as
&lt;code&gt;2015-01-02&lt;/code&gt; (or &lt;code&gt;d&quot;2015-01-02&quot;&lt;/code&gt; to avoid
confusion with infix subtraction.) You can recognize such a literal with
an Alex regular expression &lt;code&gt;$d+\-$d+\-$d+&lt;/code&gt;. However, you
won’t be able to get hold of the individual &lt;code&gt;$d+&lt;/code&gt; pieces —
Alex regexps lack capture groups. So you’ll need to use a separate date
parsing function to parse the same string second time.&lt;/p&gt;
&lt;h2 id=&quot;parsec&quot;&gt;Parsec&lt;/h2&gt;
&lt;p&gt;On the other hand, we have parser combinators that solve this problem
nicely. You define parsers for numbers; then you glue them with dashes,
and you get a parser for dates.&lt;/p&gt;
&lt;p&gt;However, using Parsec (or similar) without a separate lexer is not
the best choice:&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;&lt;p&gt;Dealing with whitespace and comments is awkward in the parser;
you need to wrap everything in a &lt;code&gt;token&lt;/code&gt; combinator. (If you
decide to do that, at least use a &lt;a
href=&quot;2013-03-31-flavours-of-free-applicative-functors&quot;&gt;free applicative
functor&lt;/a&gt; to ensure that you &lt;a
href=&quot;2014-04-20-json-validation-combinators#arrays&quot;&gt;don’t forget to
consume that whitespace&lt;/a&gt;).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Separating parsing into lexical and syntax analysis is just a
good engineering practice. It reduces the overall complexity through
«divide and conquer». The two phases usually have well-defined
responsibilities and a simple interface — why not take advantage of
that?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If a language needs the &lt;a
href=&quot;https://en.wikipedia.org/wiki/Maximal_munch&quot;&gt;maximal munch&lt;/a&gt;
rule, it’s hard to impossible to encode that with Parsec or similar
libraries.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Tokens enable the syntax analyzer to report better errors. This
is because you can tell which &lt;em&gt;token&lt;/em&gt; you didn’t expect. In a
Char-based Parsec parser, you can only tell which &lt;em&gt;character&lt;/em&gt; (or
an arbitrary number of characters) you didn’t expect, because you don’t
know what constitutes a token.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Potential performance considerations. If a parser has to try
several syntax tree alternatives, it reparses low-level lexical tokens
anew every time. From this perspective, the lexical analyzer provides a
natural «caching layer».&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;regex-applicative&quot;&gt;regex-applicative&lt;/h2&gt;
&lt;p&gt;My &lt;a
href=&quot;http://hackage.haskell.org/package/regex-applicative-0.3.0.3/docs/Text-Regex-Applicative.html&quot;&gt;regex-applicative&lt;/a&gt;
library provides applicative parser combinators with regexp semantics.
We can write a simple lexer on top of it that would give us the benefits
of both Alex and Parsec.&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb1&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb1-1&quot;&gt;&lt;a href=&quot;#cb1-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;{-# LANGUAGE OverloadedStrings, OverloadedLists #-}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-2&quot;&gt;&lt;a href=&quot;#cb1-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-3&quot;&gt;&lt;a href=&quot;#cb1-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;qualified&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Data.Text&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;T&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-4&quot;&gt;&lt;a href=&quot;#cb1-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;qualified&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Data.HashSet&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;HS&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-5&quot;&gt;&lt;a href=&quot;#cb1-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Text.Regex.Applicative&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-6&quot;&gt;&lt;a href=&quot;#cb1-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Text.Regex.Applicative.Common&lt;/span&gt; (decimal)&lt;/span&gt;
&lt;span id=&quot;cb1-7&quot;&gt;&lt;a href=&quot;#cb1-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Data.Char&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-8&quot;&gt;&lt;a href=&quot;#cb1-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Data.Time&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;For example, here’s a parser for dates. (For simplicity, this one
doesn’t check dates for validity.)&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb2&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb2-1&quot;&gt;&lt;a href=&quot;#cb2-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;pDate ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;RE&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Char&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Day&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-2&quot;&gt;&lt;a href=&quot;#cb2-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;pDate &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; fromGregorian &lt;span class=&quot;op&quot;&gt;&amp;lt;$&amp;gt;&lt;/span&gt; decimal &lt;span class=&quot;op&quot;&gt;&amp;lt;*&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;quot;-&amp;quot;&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;&amp;lt;*&amp;gt;&lt;/span&gt; decimal &lt;span class=&quot;op&quot;&gt;&amp;lt;*&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;quot;-&amp;quot;&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;&amp;lt;*&amp;gt;&lt;/span&gt; decimal&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;And here’s a parser for templates — strings that may include
interpolated variables and escaping.&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb3&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb3-1&quot;&gt;&lt;a href=&quot;#cb3-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;pTemplate ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;RE&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Char&lt;/span&gt; [&lt;span class=&quot;dt&quot;&gt;Either&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;T.Text&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;T.Text&lt;/span&gt;] &lt;span class=&quot;co&quot;&gt;-- Left = text, Right = variable&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-2&quot;&gt;&lt;a href=&quot;#cb3-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;pTemplate &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;quot;\&amp;quot;&amp;quot;&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;*&amp;gt;&lt;/span&gt; many piece &lt;span class=&quot;op&quot;&gt;&amp;lt;*&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;quot;\&amp;quot;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-3&quot;&gt;&lt;a href=&quot;#cb3-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-4&quot;&gt;&lt;a href=&quot;#cb3-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;co&quot;&gt;-- piece of text or interpolated variable&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-5&quot;&gt;&lt;a href=&quot;#cb3-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    piece &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;/span&gt;
&lt;span id=&quot;cb3-6&quot;&gt;&lt;a href=&quot;#cb3-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      (&lt;span class=&quot;dt&quot;&gt;Left&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt; T.pack &lt;span class=&quot;op&quot;&gt;&amp;lt;$&amp;gt;&lt;/span&gt; some ch) &lt;span class=&quot;op&quot;&gt;&amp;lt;|&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-7&quot;&gt;&lt;a href=&quot;#cb3-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      (&lt;span class=&quot;dt&quot;&gt;Right&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;&amp;lt;$&amp;gt;&lt;/span&gt; var)&lt;/span&gt;
&lt;span id=&quot;cb3-8&quot;&gt;&lt;a href=&quot;#cb3-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-9&quot;&gt;&lt;a href=&quot;#cb3-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;co&quot;&gt;-- interpolated variable&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-10&quot;&gt;&lt;a href=&quot;#cb3-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    var &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;quot;${&amp;quot;&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;*&amp;gt;&lt;/span&gt; pVar &lt;span class=&quot;op&quot;&gt;&amp;lt;*&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;quot;}&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-11&quot;&gt;&lt;a href=&quot;#cb3-11&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-12&quot;&gt;&lt;a href=&quot;#cb3-12&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;co&quot;&gt;-- normal character, plain or escaped&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-13&quot;&gt;&lt;a href=&quot;#cb3-13&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    ch &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-14&quot;&gt;&lt;a href=&quot;#cb3-14&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      psym (\c &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;not&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; c &lt;span class=&quot;ot&quot;&gt;`HS.member`&lt;/span&gt; escapable) &lt;span class=&quot;op&quot;&gt;&amp;lt;|&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-15&quot;&gt;&lt;a href=&quot;#cb3-15&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      (&lt;span class=&quot;st&quot;&gt;&amp;quot;\\&amp;quot;&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;*&amp;gt;&lt;/span&gt; psym (\c &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; c &lt;span class=&quot;ot&quot;&gt;`HS.member`&lt;/span&gt; escapable))&lt;/span&gt;
&lt;span id=&quot;cb3-16&quot;&gt;&lt;a href=&quot;#cb3-16&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-17&quot;&gt;&lt;a href=&quot;#cb3-17&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;co&quot;&gt;-- set of escapable characters&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-18&quot;&gt;&lt;a href=&quot;#cb3-18&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    escapable &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; [&lt;span class=&quot;ch&quot;&gt;&amp;#39;&amp;quot;&amp;#39;&lt;/span&gt;, &lt;span class=&quot;ch&quot;&gt;&amp;#39;\\&amp;#39;&lt;/span&gt;, &lt;span class=&quot;ch&quot;&gt;&amp;#39;$&amp;#39;&lt;/span&gt;]&lt;/span&gt;
&lt;span id=&quot;cb3-19&quot;&gt;&lt;a href=&quot;#cb3-19&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-20&quot;&gt;&lt;a href=&quot;#cb3-20&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    pVar &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; T.pack &lt;span class=&quot;op&quot;&gt;&amp;lt;$&amp;gt;&lt;/span&gt; some (psym &lt;span class=&quot;fu&quot;&gt;isAlpha&lt;/span&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Individual parsers are merged into a single &lt;code&gt;pToken&lt;/code&gt;
parser:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb4&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb4-1&quot;&gt;&lt;a href=&quot;#cb4-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Token&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-2&quot;&gt;&lt;a href=&quot;#cb4-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;   &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Template&lt;/span&gt; [&lt;span class=&quot;dt&quot;&gt;Either&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;T.Text&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;T.Text&lt;/span&gt;]&lt;/span&gt;
&lt;span id=&quot;cb4-3&quot;&gt;&lt;a href=&quot;#cb4-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;   &lt;span class=&quot;op&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Date&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Day&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-4&quot;&gt;&lt;a href=&quot;#cb4-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;co&quot;&gt;-- | ...&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-5&quot;&gt;&lt;a href=&quot;#cb4-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-6&quot;&gt;&lt;a href=&quot;#cb4-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;pToken ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;RE&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Char&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Token&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-7&quot;&gt;&lt;a href=&quot;#cb4-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;pToken &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-8&quot;&gt;&lt;a href=&quot;#cb4-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;   (&lt;span class=&quot;dt&quot;&gt;Template&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;&amp;lt;$&amp;gt;&lt;/span&gt; pTemplate) &lt;span class=&quot;op&quot;&gt;&amp;lt;|&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-9&quot;&gt;&lt;a href=&quot;#cb4-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;   (&lt;span class=&quot;dt&quot;&gt;Date&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;&amp;lt;$&amp;gt;&lt;/span&gt; pDate)&lt;/span&gt;
&lt;span id=&quot;cb4-10&quot;&gt;&lt;a href=&quot;#cb4-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;co&quot;&gt;-- &amp;lt;|&amp;gt; ...&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Finally, a simple tokenizing function might look something like
this:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb5&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb5-1&quot;&gt;&lt;a href=&quot;#cb5-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;tokens ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; [&lt;span class=&quot;dt&quot;&gt;Token&lt;/span&gt;]&lt;/span&gt;
&lt;span id=&quot;cb5-2&quot;&gt;&lt;a href=&quot;#cb5-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;tokens &lt;span class=&quot;st&quot;&gt;&amp;quot;&amp;quot;&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; []&lt;/span&gt;
&lt;span id=&quot;cb5-3&quot;&gt;&lt;a href=&quot;#cb5-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;tokens s &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-4&quot;&gt;&lt;a href=&quot;#cb5-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;let&lt;/span&gt; re &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;Just&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;&amp;lt;$&amp;gt;&lt;/span&gt; pToken) &lt;span class=&quot;op&quot;&gt;&amp;lt;|&amp;gt;&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;Nothing&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;&amp;lt;$&lt;/span&gt; some (psym &lt;span class=&quot;fu&quot;&gt;isSpace&lt;/span&gt;)) &lt;span class=&quot;kw&quot;&gt;in&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-5&quot;&gt;&lt;a href=&quot;#cb5-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;case&lt;/span&gt; findLongestPrefix re s &lt;span class=&quot;kw&quot;&gt;of&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-6&quot;&gt;&lt;a href=&quot;#cb5-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;dt&quot;&gt;Just&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;Just&lt;/span&gt; tok, rest) &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; tok &lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; tokens rest&lt;/span&gt;
&lt;span id=&quot;cb5-7&quot;&gt;&lt;a href=&quot;#cb5-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;dt&quot;&gt;Just&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;Nothing&lt;/span&gt;, rest) &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; tokens rest &lt;span class=&quot;co&quot;&gt;-- whitespace&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-8&quot;&gt;&lt;a href=&quot;#cb5-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;dt&quot;&gt;Nothing&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;error&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;quot;lexical error&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The resulting token list can be further parsed with Parsec or
Happy.&lt;/p&gt;
&lt;p&gt;This simple function can be extended to do a lot more:&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;Track position in the input string, use it for error reporting,
include it into tokens&lt;/li&gt;
&lt;li&gt;Consume input incrementally&lt;/li&gt;
&lt;li&gt;Get feedback from the syntax analyzer, and, depending on the
syntactic context, perform different lexical analyses. This is useful
for more complex features of programming languages, such as the off-side
rule in Haskell or arbitrarily-nested command substitution and «here
documents» in POSIX Shell. (This is another thing Alex cannot do, by the
way.)&lt;/li&gt;
&lt;/ol&gt;
</description>
                        <pubDate>Fri, 02 Jan 2015 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2015-01-02-lexical-analysis</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2015-01-02-lexical-analysis.html</guid>
                </item>
        
                <item>
                        <title>Denotational design does not work</title>
                        <description>&lt;p&gt;Conal Elliott in his paper &lt;a
href=&quot;http://conal.net/papers/type-class-morphisms/type-class-morphisms-long.pdf&quot;&gt;Denotational
design with type class morphisms&lt;/a&gt;, as well as in the recent &lt;a
href=&quot;http://www.haskellcast.com/episode/009-conal-elliott-on-frp-and-denotational-design/&quot;&gt;podcast&lt;/a&gt;,
advocates denotational design as a principle of software design.
Unfortunately, in my experience it never works for realistically complex
problems.&lt;/p&gt;
&lt;h2 id=&quot;on-simplicity&quot;&gt;On simplicity&lt;/h2&gt;
&lt;p&gt;First, I’ll formulate Conal’s approach as I understand it. For any
given entity of your model, you should come up with a simple
mathematical object — the &lt;em&gt;denotation&lt;/em&gt; — that faithfully
represents that entity.&lt;/p&gt;
&lt;p&gt;The implementation of the type may vary, presumably to maximize its
runtime efficiency, but it should not expose any more information than
the chosen denotation has. That is considered an «abstraction leak».
Conal specifically talks about that in the podcast (31m50s, for
example).&lt;/p&gt;
&lt;p&gt;Here I need to stress an important but subtle point in Conal’s
principle: &lt;em&gt;simplicity&lt;/em&gt;. You only follow Conal’s principle if you
find a &lt;em&gt;simple&lt;/em&gt; denotation, not just any denotation.&lt;/p&gt;
&lt;p&gt;This point is important because without it any design is denotational
design, trivially. Universal algebra tells us that for &lt;em&gt;any&lt;/em&gt; set
of operations and &lt;em&gt;any&lt;/em&gt; (non-contradictory) laws about them there
exists a model that satisfies these laws. For any Haskell module, we can
interpret its types in the set theory (or a more complex domain if
needed), and call that our denotation.&lt;/p&gt;
&lt;p&gt;But that’s not what Conal is after. His approach is interesting
exactly because he argues that it is possible to find &lt;em&gt;simple&lt;/em&gt;
denotations. This subtle point makes Conal’s approach simultaneously
attractive and unrealistic. I’ll demonstrate this with two examples from
my own work experience.&lt;/p&gt;
&lt;h2 id=&quot;dsls&quot;&gt;DSLs&lt;/h2&gt;
&lt;p&gt;At Barclays I worked on &lt;a
href=&quot;http://arbitrary.name/papers/fpf.pdf&quot;&gt;FPF&lt;/a&gt;, an embedded
domain-specific language for describing financial instruments. In his
paper, Conal shows how a denotation for such a DSL can quickly grow in
complexity when requirements change. When variables and errors are
introduced, the denotation changes from &lt;code&gt;a&lt;/code&gt; to
&lt;code&gt;Env -&amp;gt; Result a&lt;/code&gt;. Still, this is a very simple DSL that
only supports evaluation.&lt;/p&gt;
&lt;p&gt;In reality, the main reason people make DSLs instead of using
general-purpose languages is the ability to analyze DSL programs. One
important feature of FPF is that it could pretty-print a program into a
nice PDF. That poses an obvious problem — not every two semantically
equivalent programs (under the interpretation semantics) result in
equally nice PDFs. Inlining is a semantically sound transformation, but
when our users get PDFs with all the definitions inlined, they get
angry.&lt;/p&gt;
&lt;p&gt;Sure, we could say that now our denotation becomes the domain product
&lt;code&gt;(Env -&amp;gt; Result a, String)&lt;/code&gt;, where &lt;code&gt;String&lt;/code&gt; is
the pretty printer output. But in reality we have a dozen different
analyses, and most of them are not expressible in terms of each other,
or any single simple model. They also do not satisfy many laws. For
instance, one day a user (quant or trader) could come and tell us that
the barrier classifier should classify two mathematically equivalent
expressions as different barriers because those expressions follow
certain conventions. And even though the quant is mathematically
inclined, denotations and type class morphism would be the last thing he
wants to hear about in response to his feature request.&lt;/p&gt;
&lt;p&gt;So, in practice, the best denotation for the DSL expressions was the
AST itself. Which, according to my interpretation of Conal’s principles,
is not an example of a denotational design, but a failure to apply
one.&lt;/p&gt;
&lt;h2 id=&quot;machines&quot;&gt;Machines&lt;/h2&gt;
&lt;p&gt;At my current job (&lt;a href=&quot;http://signalvine.com&quot;&gt;Signal Vine&lt;/a&gt;),
I work on a platform for scripted interaction with students via text
messages. For every student enrolled in a messaging campaign, we send a
message, receive a reply, process it, and the cycle repeats.&lt;/p&gt;
&lt;p&gt;This is very similar to FRP; perhaps not the FRP Conal prefers (in
the podcast he stresses the importance of continuous functions as
opposed to events), but the kind of discrete FRP that Justin Le &lt;a
href=&quot;http://blog.jle.im/entry/intro-to-machines-arrows-part-1-stream-and&quot;&gt;models&lt;/a&gt;
with Mealy machines.&lt;/p&gt;
&lt;p&gt;So it would seem that I should model a student as&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb1&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb1-1&quot;&gt;&lt;a href=&quot;#cb1-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;newtype&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Student&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Student&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;InboundSMS&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;OutboundSMS&lt;/span&gt;, &lt;span class=&quot;dt&quot;&gt;Student&lt;/span&gt;))&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;That would be an exemplary case of denotational design. But that
would be far from our customers’ needs. Every student has a set of
profile variables that are filled when the student responds to a text,
and our customers (counselors who work with that student) want to see
those variables. They also want to see which messages were sent, what
the student’s replies were, and even what messages will be sent to the
student in the future. These requirements defeat the attempt to model a
student in a simple, abstract way. Instead, I need to store all the
information I have about the student because sooner or later I’ll need
to expose that information to the user.&lt;/p&gt;
&lt;h2 id=&quot;conclusions&quot;&gt;Conclusions&lt;/h2&gt;
&lt;p&gt;Denotational design is a very neat idea, but I believe that it only
works in simple cases and when requirements are static. In real-world
commercial programming, it breaks for two main reasons:&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;Users often want maximum insight into what’s going on, and you need
to break the abstraction to deliver that information.&lt;/li&gt;
&lt;li&gt;Requirements change, and an innocent change in requirements may lead
to a drastic change and increase in complexity of the denotation.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;It is certainly useful to &lt;em&gt;think&lt;/em&gt; about denotations of your
entities in specific, simple contexts (like the evaluation semantics for
a DSL); such thought experiments may help you better understand the
problem or even find a flaw in your implementation.&lt;/p&gt;
&lt;p&gt;But when you are implementing the actual type, your best bet is to
create an algebraic data type with all the information you have, so that
when you need to extend the interface (or «leak the abstraction»), it
won’t cause you too much pain.&lt;/p&gt;
</description>
                        <pubDate>Wed, 31 Dec 2014 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2014-12-31-denotational-design-does-not-work</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2014-12-31-denotational-design-does-not-work.html</guid>
                </item>
        
                <item>
                        <title>Taking advantage of type synonyms in monad-control</title>
                        <description>&lt;p&gt;Bas van Dijk has recently released &lt;a
href=&quot;https://hackage.haskell.org/package/monad-control-1.0.0.0&quot;&gt;monad-control-1.0.0.0&lt;/a&gt;,
the main purpose of which is to replace associated data types with
associated type synonyms. The change caused minor breakages here and
there, so people might wonder whether and why it was worth it. Let me
show you a simple example that demonstrates the difference.&lt;/p&gt;
&lt;!--more--&gt;
&lt;hr /&gt;
&lt;p&gt;Let’s say we are writing a web application. &lt;a
href=&quot;https://hackage.haskell.org/package/wai-3.0.2/docs/Network-Wai.html&quot;&gt;wai&lt;/a&gt;
defines an application as&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb1&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb1-1&quot;&gt;&lt;a href=&quot;#cb1-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Application&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-2&quot;&gt;&lt;a href=&quot;#cb1-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;dt&quot;&gt;Request&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-3&quot;&gt;&lt;a href=&quot;#cb1-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  (&lt;span class=&quot;dt&quot;&gt;Response&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;IO&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;ResponseReceived&lt;/span&gt;) &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-4&quot;&gt;&lt;a href=&quot;#cb1-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;dt&quot;&gt;IO&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;ResponseReceived&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Our web app will need a database connection, which we’ll pass using
the &lt;code&gt;ReaderT&lt;/code&gt; transformer:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb2&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb2-1&quot;&gt;&lt;a href=&quot;#cb2-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;ApplicationM&lt;/span&gt; m &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-2&quot;&gt;&lt;a href=&quot;#cb2-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;dt&quot;&gt;Request&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-3&quot;&gt;&lt;a href=&quot;#cb2-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  (&lt;span class=&quot;dt&quot;&gt;Response&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; m &lt;span class=&quot;dt&quot;&gt;ResponseReceived&lt;/span&gt;) &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-4&quot;&gt;&lt;a href=&quot;#cb2-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  m &lt;span class=&quot;dt&quot;&gt;ResponseReceived&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-5&quot;&gt;&lt;a href=&quot;#cb2-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-6&quot;&gt;&lt;a href=&quot;#cb2-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;myApp ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;ApplicationM&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;ReaderT&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;DbConnection&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;IO&lt;/span&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;However, &lt;a
href=&quot;https://hackage.haskell.org/package/warp-3.0.4/docs/Network-Wai-Handler-Warp.html&quot;&gt;warp&lt;/a&gt;
can only run an &lt;code&gt;Application&lt;/code&gt;, not
&lt;code&gt;ApplicationM&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb3&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb3-1&quot;&gt;&lt;a href=&quot;#cb3-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;run ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Port&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Application&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;IO&lt;/span&gt; ()&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Can we build
&lt;code&gt;runM :: Port -&amp;gt; ApplicationM m -&amp;gt; m ()&lt;/code&gt; on top of the
simple &lt;code&gt;run&lt;/code&gt; function? Solving the problems like this one is
exactly the purpose of monad-control.&lt;/p&gt;
&lt;p&gt;Here’s how such a function might look like:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb4&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb4-1&quot;&gt;&lt;a href=&quot;#cb4-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;runM&lt;/span&gt;
&lt;span id=&quot;cb4-2&quot;&gt;&lt;a href=&quot;#cb4-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;  ::&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;MonadBaseControl&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;IO&lt;/span&gt; m)&lt;/span&gt;
&lt;span id=&quot;cb4-3&quot;&gt;&lt;a href=&quot;#cb4-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;ot&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Port&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;ApplicationM&lt;/span&gt; m &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; m ()&lt;/span&gt;
&lt;span id=&quot;cb4-4&quot;&gt;&lt;a href=&quot;#cb4-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;runM port app &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-5&quot;&gt;&lt;a href=&quot;#cb4-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  liftBaseWith &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; \runInIO &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-6&quot;&gt;&lt;a href=&quot;#cb4-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    run port &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; \req ack &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; runInIO &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; app req (liftBase &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt; ack)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;What’s going on here? &lt;code&gt;liftBaseWith&lt;/code&gt;, like
&lt;code&gt;liftM&lt;/code&gt; or &lt;code&gt;liftBase&lt;/code&gt;, allows to run a primitive
monadic action in a complex monad stack. The difference is that it also
gives us a function, here named &lt;code&gt;runInIO&lt;/code&gt;, which lets to
“lower” complex actions to primitive ones. Here we use
&lt;code&gt;runInIO&lt;/code&gt; to translate the return value of our app,
&lt;code&gt;m ()&lt;/code&gt;, into a basic &lt;code&gt;IO ()&lt;/code&gt; value that the
&lt;code&gt;run&lt;/code&gt; function can digest.&lt;/p&gt;
&lt;p&gt;All is well, except…&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Could not deduce (StM m ResponseReceived ~ ResponseReceived)
Expected type: IO ResponseReceived
  Actual type: IO (StM m ResponseReceived)
Relevant bindings include
  runInIO :: RunInBase m IO
In the expression: runInIO $ app req (liftBase . ack)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The type of &lt;code&gt;runInIO&lt;/code&gt; is
&lt;code&gt;forall a . m a -&amp;gt; IO (StM m a)&lt;/code&gt; (a.k.a.
&lt;code&gt;RunInBase m IO&lt;/code&gt;), while we would like a simple
&lt;code&gt;forall a . m a -&amp;gt; IO a&lt;/code&gt;. The purpose of &lt;code&gt;StM&lt;/code&gt;
is to encompass any “output effects”, such as state or error.&lt;/p&gt;
&lt;p&gt;In our case, we don’t have any “output effects” (nor would we be
allowed to), so
&lt;code&gt;StM (ReaderT DbConnection IO) ResponseReceived&lt;/code&gt; is really
isomorphic to &lt;code&gt;ResponseReceived&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;In monad-control 0.x, &lt;code&gt;StM&lt;/code&gt; used to be an associated data
family, and its constructors for the standard monad transformers were
hidden. Even though we knew that the above two types were isomorphic, we
still couldn’t resolve the error nicely.&lt;/p&gt;
&lt;p&gt;Not anymore! Since in monad-control 1.0 &lt;code&gt;StM&lt;/code&gt; is an
associated type synonym,
&lt;code&gt;StM (ReaderT DbConnection IO) ResponseReceived&lt;/code&gt; and
&lt;code&gt;ResponseReceived&lt;/code&gt; are not just hypothetically isomorphic;
they are literally the same type. After we add the corresponding
equality constraint to &lt;code&gt;runM&lt;/code&gt;&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb6&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb6-1&quot;&gt;&lt;a href=&quot;#cb6-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;runM&lt;/span&gt;
&lt;span id=&quot;cb6-2&quot;&gt;&lt;a href=&quot;#cb6-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;  ::&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;MonadBaseControl&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;IO&lt;/span&gt; m, &lt;span class=&quot;dt&quot;&gt;StM&lt;/span&gt; m &lt;span class=&quot;dt&quot;&gt;ResponseReceived&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;~&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;ResponseReceived&lt;/span&gt;)&lt;/span&gt;
&lt;span id=&quot;cb6-3&quot;&gt;&lt;a href=&quot;#cb6-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;ot&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Port&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;ApplicationM&lt;/span&gt; m &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; m ()&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;our app compiles!&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;This example is not just an isolated case. The general problem with
monad-control is that it is all too easy to discard the output effects
as Edward Yang &lt;a
href=&quot;http://blog.ezyang.com/2012/01/monadbasecontrol-is-unsound/&quot;&gt;shows&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Monads for which &lt;code&gt;StM m a ~ a&lt;/code&gt; provide a “safe subset” of
monad-control. Let’s call them “stateless” monads.&lt;/p&gt;
&lt;p&gt;Previously, it was hard to tell apart stateless and stateful monads
because the output effects or absence thereof hid behind the opaque StM
data family.&lt;/p&gt;
&lt;p&gt;Now not only is it transparent when the output effects are absent,
but we can actually encode that fact right in the type system! As an
example, Mitsutoshi Aoe and I are &lt;a
href=&quot;https://github.com/maoe/lifted-async/pull/7&quot;&gt;experimenting&lt;/a&gt;
with a safe lifted async module.&lt;/p&gt;
&lt;p&gt;One may wonder if this subset is too boring, since it only includes
monads that are isomorphic to a reader transformer over the base monad.
While that is technically true, there are a lot of things you can do
with a reader. The &lt;code&gt;ZoomT&lt;/code&gt; and &lt;code&gt;CustomWriterT&lt;/code&gt;
transformers that I described in &lt;a
href=&quot;/articles/2014-12-06-abstracting-from-transformer#other-cool-tricks&quot;&gt;another
article&lt;/a&gt;, as well as the &lt;code&gt;Proxied&lt;/code&gt; transformer they’re
based upon, are stateless and thus safe to use with monad-control.&lt;/p&gt;
&lt;p&gt;Another common example of a stateless monad transformer is a
&lt;code&gt;ReaderT&lt;/code&gt; holding a reference (such as &lt;code&gt;IORef&lt;/code&gt;,
&lt;code&gt;TVar&lt;/code&gt;, or &lt;code&gt;MVar&lt;/code&gt;). This is commonly used to
maintain a shared state in multithreaded server applications, so it is
fortunate that we can fork threads and catch exceptions inside such
monads.&lt;/p&gt;
</description>
                        <pubDate>Fri, 26 Dec 2014 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2014-12-26-monad-control-type-synonyms</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2014-12-26-monad-control-type-synonyms.html</guid>
                </item>
        
                <item>
                        <title>Extensible effects: abstracting from the transformer
</title>
                        <description>&lt;p&gt;In &lt;a href=&quot;2014-07-15-type-based-lift.html&quot;&gt;Type-based lift&lt;/a&gt;, we
saw a way to lift monadic actions automatically to the right layer of a
multilayer monad transformer stack, based only on the types
involved.&lt;/p&gt;
&lt;p&gt;Namely, we defined a closed type family&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb1&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb1-1&quot;&gt;&lt;a href=&quot;#cb1-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;family&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Find&lt;/span&gt; (&lt;span class=&quot;ot&quot;&gt;t ::&lt;/span&gt; (&lt;span class=&quot;op&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;*&lt;/span&gt;) &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; (&lt;span class=&quot;op&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;*&lt;/span&gt;)) (&lt;span class=&quot;ot&quot;&gt;m ::&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;*&lt;/span&gt;)&lt;span class=&quot;ot&quot;&gt; ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Nat&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-2&quot;&gt;&lt;a href=&quot;#cb1-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;dt&quot;&gt;Find&lt;/span&gt; t (t m) &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Zero&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-3&quot;&gt;&lt;a href=&quot;#cb1-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;dt&quot;&gt;Find&lt;/span&gt; t (p m) &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Suc&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;Find&lt;/span&gt; t m)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;that computes the type-level index of the layer &lt;code&gt;t&lt;/code&gt; in the
stack &lt;code&gt;m&lt;/code&gt;. Such an index can then be used to construct an
appropriate lifting function of type &lt;code&gt;t n a -&amp;gt; m a&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;This works well as a shortcut, so instead of writing
&lt;code&gt;lift&lt;/code&gt;, or &lt;code&gt;lift . lift&lt;/code&gt;, or
&lt;code&gt;lift . lift . lift&lt;/code&gt;, we can write &lt;code&gt;magicLift&lt;/code&gt;,
and let it figure out how far to lift.&lt;/p&gt;
&lt;p&gt;However, the lifting is expressed in terms of specific transformers,
and not the effects they can handle. For example, a stateful computation
may target the strict State monad or the lazy one, but not both, because
they are implemented by distinct types.&lt;/p&gt;
&lt;p&gt;Let’s fix this!&lt;/p&gt;
&lt;!--more--&gt;
&lt;h2 id=&quot;cando&quot;&gt;CanDo&lt;/h2&gt;
&lt;p&gt;To know which effects can be handled by each transformer, we’ll
introduce a new type family, &lt;code&gt;CanDo&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb2&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb2-1&quot;&gt;&lt;a href=&quot;#cb2-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;family&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;CanDo&lt;/span&gt; (&lt;span class=&quot;ot&quot;&gt;m ::&lt;/span&gt; (&lt;span class=&quot;op&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;*&lt;/span&gt;)) (&lt;span class=&quot;ot&quot;&gt;eff ::&lt;/span&gt; k)&lt;span class=&quot;ot&quot;&gt; ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Bool&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now we need to modify the &lt;code&gt;Find&lt;/code&gt; family to find the first
(top-most) layer for which the &lt;code&gt;CanDo&lt;/code&gt; predicate will return
&lt;code&gt;True&lt;/code&gt;. Since on the type level we don’t have lambdas and
case statements, doing so is a bit cumbersome but still possible:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb3&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb3-1&quot;&gt;&lt;a href=&quot;#cb3-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;family&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;MapCanDo&lt;/span&gt; (&lt;span class=&quot;ot&quot;&gt;eff ::&lt;/span&gt; k) (&lt;span class=&quot;ot&quot;&gt;stack ::&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;*&lt;/span&gt;)&lt;span class=&quot;ot&quot;&gt; ::&lt;/span&gt; [&lt;span class=&quot;dt&quot;&gt;Bool&lt;/span&gt;] &lt;span class=&quot;kw&quot;&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-2&quot;&gt;&lt;a href=&quot;#cb3-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;dt&quot;&gt;MapCanDo&lt;/span&gt; eff (t m) &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;CanDo&lt;/span&gt; (t m) eff) &amp;#39;&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;MapCanDo&lt;/span&gt; eff m&lt;/span&gt;
&lt;span id=&quot;cb3-3&quot;&gt;&lt;a href=&quot;#cb3-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;dt&quot;&gt;MapCanDo&lt;/span&gt; eff m &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &amp;#39;[ &lt;span class=&quot;dt&quot;&gt;CanDo&lt;/span&gt; m eff ]&lt;/span&gt;
&lt;span id=&quot;cb3-4&quot;&gt;&lt;a href=&quot;#cb3-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-5&quot;&gt;&lt;a href=&quot;#cb3-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;family&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;FindTrue&lt;/span&gt; (&lt;span class=&quot;ot&quot;&gt;bs ::&lt;/span&gt; [&lt;span class=&quot;dt&quot;&gt;Bool&lt;/span&gt;])&lt;span class=&quot;ot&quot;&gt; ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Nat&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-6&quot;&gt;&lt;a href=&quot;#cb3-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;dt&quot;&gt;FindTrue&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;True&lt;/span&gt; &amp;#39;&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; t) &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Zero&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-7&quot;&gt;&lt;a href=&quot;#cb3-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;dt&quot;&gt;FindTrue&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;False&lt;/span&gt; &amp;#39;&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; t) &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Suc&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;FindTrue&lt;/span&gt; t)&lt;/span&gt;
&lt;span id=&quot;cb3-8&quot;&gt;&lt;a href=&quot;#cb3-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-9&quot;&gt;&lt;a href=&quot;#cb3-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Find&lt;/span&gt; eff (&lt;span class=&quot;ot&quot;&gt;m ::&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;*&lt;/span&gt;) &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;FindTrue&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;MapCanDo&lt;/span&gt; eff m)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Next, we need to introduce dummy types denoting effects, and relate
them to transformers:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb4&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb4-1&quot;&gt;&lt;a href=&quot;#cb4-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;qualified&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Control.Monad.Trans.State.Lazy&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;SL&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-2&quot;&gt;&lt;a href=&quot;#cb4-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;qualified&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Control.Monad.Trans.State.Strict&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;SS&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-3&quot;&gt;&lt;a href=&quot;#cb4-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-4&quot;&gt;&lt;a href=&quot;#cb4-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;EffState&lt;/span&gt; (&lt;span class=&quot;ot&quot;&gt;s ::&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;*&lt;/span&gt;)&lt;/span&gt;
&lt;span id=&quot;cb4-5&quot;&gt;&lt;a href=&quot;#cb4-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;EffWriter&lt;/span&gt; (&lt;span class=&quot;ot&quot;&gt;w ::&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;*&lt;/span&gt;)&lt;/span&gt;
&lt;span id=&quot;cb4-6&quot;&gt;&lt;a href=&quot;#cb4-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;EffReader&lt;/span&gt; (&lt;span class=&quot;ot&quot;&gt;e ::&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;*&lt;/span&gt;)&lt;/span&gt;
&lt;span id=&quot;cb4-7&quot;&gt;&lt;a href=&quot;#cb4-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-8&quot;&gt;&lt;a href=&quot;#cb4-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;instance&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;CanDo&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;SS.StateT&lt;/span&gt; s m) eff &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;StateCanDo&lt;/span&gt; s eff&lt;/span&gt;
&lt;span id=&quot;cb4-9&quot;&gt;&lt;a href=&quot;#cb4-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;instance&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;CanDo&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;SL.StateT&lt;/span&gt; s m) eff &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;StateCanDo&lt;/span&gt; s eff&lt;/span&gt;
&lt;span id=&quot;cb4-10&quot;&gt;&lt;a href=&quot;#cb4-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-11&quot;&gt;&lt;a href=&quot;#cb4-11&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;family&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;StateCanDo&lt;/span&gt; s eff &lt;span class=&quot;kw&quot;&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-12&quot;&gt;&lt;a href=&quot;#cb4-12&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;dt&quot;&gt;StateCanDo&lt;/span&gt; s (&lt;span class=&quot;dt&quot;&gt;EffState&lt;/span&gt; s) &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;True&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-13&quot;&gt;&lt;a href=&quot;#cb4-13&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;dt&quot;&gt;StateCanDo&lt;/span&gt; s (&lt;span class=&quot;dt&quot;&gt;EffReader&lt;/span&gt; s) &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;True&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-14&quot;&gt;&lt;a href=&quot;#cb4-14&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;dt&quot;&gt;StateCanDo&lt;/span&gt; s (&lt;span class=&quot;dt&quot;&gt;EffWriter&lt;/span&gt; s) &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;True&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-15&quot;&gt;&lt;a href=&quot;#cb4-15&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;dt&quot;&gt;StateCanDo&lt;/span&gt; s eff &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;False&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;As we see, the relationship between effects and transformers is
many-to-many. A single effect can be implemented by multiple
transformers, and a single transformer can implement multiple
effects.&lt;/p&gt;
&lt;h2 id=&quot;should-statet-implement-effreader&quot;&gt;Should StateT implement
EffReader?&lt;/h2&gt;
&lt;p&gt;It’s not only for demonstration that I made &lt;code&gt;StateT&lt;/code&gt;
implement the &lt;code&gt;EffReader&lt;/code&gt; effect. One can view
&lt;code&gt;EffReader&lt;/code&gt; (and &lt;code&gt;EffWriter&lt;/code&gt;) computations as a
subclass of all stateful computations&lt;/p&gt;
&lt;p&gt;Suppose that you have two computations with the same state that you
want to execute sequentially, but one of them only needs read access to
the state. Why not express that fact in its type?&lt;/p&gt;
&lt;h2 id=&quot;other-cool-tricks&quot;&gt;Other cool tricks&lt;/h2&gt;
&lt;p&gt;Here are a couple of cool (and useful!) tricks that are possible with
extensible effects. I will only describe what they do and not how
they’re implemented; you can find all code in the &lt;a
href=&quot;https://github.com/UnkindPartition/monad-classes&quot;&gt;repo&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&quot;zooming&quot;&gt;Zooming&lt;/h3&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb5&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb5-1&quot;&gt;&lt;a href=&quot;#cb5-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;newtype&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;ZoomT&lt;/span&gt; big small m a &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;...&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;ZoomT&lt;/code&gt; handles &lt;code&gt;EffState small&lt;/code&gt; effects by
transforming them to &lt;code&gt;EffState big&lt;/code&gt; effects. To enable this,
we must supply a lens from &lt;code&gt;big&lt;/code&gt; into &lt;code&gt;small&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb6&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb6-1&quot;&gt;&lt;a href=&quot;#cb6-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;runZoom&lt;/span&gt;
&lt;span id=&quot;cb6-2&quot;&gt;&lt;a href=&quot;#cb6-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;  ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Lens&lt;/span&gt; big small &lt;/span&gt;
&lt;span id=&quot;cb6-3&quot;&gt;&lt;a href=&quot;#cb6-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;ZoomT&lt;/span&gt; big small m a&lt;/span&gt;
&lt;span id=&quot;cb6-4&quot;&gt;&lt;a href=&quot;#cb6-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; m a&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Compared to traditional zooming (as in &lt;a
href=&quot;https://hackage.haskell.org/package/lens-4.6.0.1/docs/Control-Lens-Zoom.html&quot;&gt;lens&lt;/a&gt;),
where we can only focus on a single state at a time, here we can apply
many &lt;code&gt;ZoomT&lt;/code&gt;s stacked on top of each other, thus handling
multiple different &lt;code&gt;EffState&lt;/code&gt; effects simultaneously.&lt;/p&gt;
&lt;h3 id=&quot;custom-writer-handlers&quot;&gt;Custom Writer handlers&lt;/h3&gt;
&lt;p&gt;The classic use case for a Writer monad is logging. Ironically, the
way a writer monad does logging (accumulating log messages in memory) is
wrong for almost all purposes, and possible right ways (flushing
messages to disk or sending them over the network) are out of reach for
it.&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb7&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb7-1&quot;&gt;&lt;a href=&quot;#cb7-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;newtype&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;CustomWriterT&lt;/span&gt; w m a &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;...&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb7-2&quot;&gt;&lt;a href=&quot;#cb7-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb7-3&quot;&gt;&lt;a href=&quot;#cb7-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;evalWriterWith&lt;/span&gt;
&lt;span id=&quot;cb7-4&quot;&gt;&lt;a href=&quot;#cb7-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;  ::&lt;/span&gt; (w &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; m ())&lt;/span&gt;
&lt;span id=&quot;cb7-5&quot;&gt;&lt;a href=&quot;#cb7-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;CustomWriterT&lt;/span&gt; w m a&lt;/span&gt;
&lt;span id=&quot;cb7-6&quot;&gt;&lt;a href=&quot;#cb7-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; m a&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The idea here is that &lt;code&gt;CustomWriterT&lt;/code&gt; handles
&lt;code&gt;EffWriter&lt;/code&gt; effect by calling the given handler for it —
exactly what we wanted!&lt;/p&gt;
</description>
                        <pubDate>Sat, 06 Dec 2014 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2014-12-06-abstracting-from-transformer</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2014-12-06-abstracting-from-transformer.html</guid>
                </item>
        
                <item>
                        <title>Rebalancing open source portfolio</title>
                        <description>&lt;p&gt;Being an open source developer means being an investor. I invest my
time in creating, contributing to, and maintaining projects. As an
investor, I occasionally need to re-evaluate my portfolio and decide
whether it is optimal.&lt;/p&gt;
&lt;p&gt;The result of a recent such re-evaluation is that I’ve decided to
stop my active involvement in the &lt;a
href=&quot;https://github.com/haskell-suite/&quot;&gt;haskell-suite&lt;/a&gt; family of
projects.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;This decision wasn’t easy. Being a maintainer of haskell-src-exts was
a unique experience. During the last two years, 24 people have
contributed to the project, which is amazing, given its complexity.
During ICFP’14, I met with 4 or 5 contributors and many users of
haskell-src-exts. People would approach me in the hallway and ask when
the new version would be released or a certain feature added.&lt;/p&gt;
&lt;p&gt;Leaving haskell-names behind is also sad. It hasn’t seen as many uses
as haskell-src-exts (which has always been puzzling — you can’t do much
with a bare parser. But apparently folks prefer to roll their own,
incomplete and buggy, name resolution.) Still, it’s used by fay, and I
feel bad about letting the fay devs down.&lt;/p&gt;
&lt;p&gt;So, why did I choose to stop investing in the haskell suite?&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;I have much less spare time these days, so I &lt;em&gt;have&lt;/em&gt; to drop
something.&lt;/li&gt;
&lt;li&gt;I became involved with the haskell suite because of my interest in
developer tools for Haskell (hasfix, ariadne). I am no longer working on
those, and I’m not using any haskell-src-exts-powered tools (hlint,
stylish-haskell) myself, which means I don’t get big personal returns on
my investment.&lt;/li&gt;
&lt;li&gt;The main competitor for the haskell suite is the GHC API. It is now
clear to me that we are losing to them in most areas. There is very
little hope for the type checker, let alone other parts of the
compilation pipeline. The community did a great job in catching up with
GHC on the parser side, but we still have less resources than GHC and
are bound to lag behind, it seems. On the other side, there has been
some work recently (by Alan Zimmerman, in particular) to improve GHC’s
AST and catch up with HSE on that front. So, even if I decide to invest
in compilers or dev tools in the future, I’m probably going to team up
with GHC instead.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;What’s going to happen to these projects I’m leaving behind? I’m less
worried about haskell-src-exts. Peter Jonsson has been doing some great
work on it, and I hope he’ll step in. There’s also Niklas Broberg and
all the wonderful contributors.&lt;/p&gt;
&lt;p&gt;I’m more worried about haskell-names, haskell-packages, ariadne. If
you are willing to take over any of them, let me know (and you can count
on my help). Otherwise, I’m going to provide very basic support for
them, but nothing more.&lt;/p&gt;
&lt;p&gt;Oh, and in case you missed the announcement, I’m &lt;a
href=&quot;https://groups.google.com/forum/#!topic/haskell-cafe/OaJ2rRFfmpE&quot;&gt;dropping
support&lt;/a&gt; for my test-framework packages, too.&lt;/p&gt;
&lt;p&gt;On the other hand (and to end with something positive), I have no
intention to stop maintaining tasty in the foreseeable future. Haskell
needs at least one decent testing framework, after all! :-) By the way,
here’s a cool use case for tasty that Lars Hupel shared for the upcoming
edition of HCAR:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Technische Universität München uses Tasty to assess homework
submitted for the introductory functional programming course, which is
compulsory for second-year Bachelor’s students in computer science.
Students can upload their source code to a web application, which
compiles them and executes tests (mostly QuickCheck). Graphical reports
are generated with ‘tasty-html’ and presented to the students. Grading
happens automatically with a custom test reporter, which – roughly
speaking – checks that a minimum number of significant tests have
passed. This is a huge improvement over the past years, where tests were
run by a homegrown framework which offered only textual output. Tasty
however is nicely extensible and allows for easy customization to the
instructors’ and students’ needs.&lt;/p&gt;
&lt;/blockquote&gt;
</description>
                        <pubDate>Sat, 01 Nov 2014 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2014-11-01-rebalancing-open-source-portfolio</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2014-11-01-rebalancing-open-source-portfolio.html</guid>
                </item>
        
                <item>
                        <title>Dependent Haskell</title>
                        <description>&lt;p&gt;Emulating dependent types (and, more generally, advanced type-level
programming) has been a hot topic in the Haskell community recently.
Some incredible work has been done in this direction: GADTs, open and
closed type families, singletons, etc. The plan is to copy even more
features to the type level, like type classes and GADTs, and simplify
the promotion of value-level functions.&lt;/p&gt;
&lt;p&gt;On the other hand, there’s a good deal of scepticism around this
idea. «If you want to program like in Agda, why don’t you program in
Agda?»&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;First, libraries. It took us many years to arrive at the state of
hackage that is suitable for industrial usage — and we still don’t have
satisfactory answers to many problems.&lt;/p&gt;
&lt;p&gt;My guess is that it will take at least as long as that for the
dependently typed community to arrive at this point — not only because
of the smaller community, but also because they will look for even more
type-safe solutions, which is naturally a harder problem.&lt;/p&gt;
&lt;p&gt;Second, the compiler/runtime. How optimized is the generated code? Is
there a profiler? How about concurrency and parallelism? Is there an
FFI? How good is the garbage collector?&lt;/p&gt;
&lt;p&gt;These questions are especially acute for Idris, which chose to have
its own compiler. Code extraction into Haskell or OCaml may be a more
viable alternative, but without having several real-world projects that
are implemented this way it’s very hard to assess it properly.&lt;/p&gt;
&lt;p&gt;No doubt, these (or other) languages will get there sooner or later.
But it seems that practical dependently typed programming will become
viable in Haskell much sooner than in Agda or Idris.&lt;/p&gt;
</description>
                        <pubDate>Fri, 05 Sep 2014 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2014-09-05-dependent-haskell</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2014-09-05-dependent-haskell.html</guid>
                </item>
        
                <item>
                        <title>What you need to know about bracket</title>
                        <description>&lt;p&gt;The &lt;code&gt;bracket&lt;/code&gt; function in Haskell can be used to release
resources reliably:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb1&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb1-1&quot;&gt;&lt;a href=&quot;#cb1-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;bracket&lt;/span&gt;
&lt;span id=&quot;cb1-2&quot;&gt;&lt;a href=&quot;#cb1-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;        ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;IO&lt;/span&gt; a         &lt;span class=&quot;co&quot;&gt;-- ^ computation to run first (&amp;quot;acquire resource&amp;quot;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-3&quot;&gt;&lt;a href=&quot;#cb1-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;        &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; (a &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;IO&lt;/span&gt; b)  &lt;span class=&quot;co&quot;&gt;-- ^ computation to run last (&amp;quot;release resource&amp;quot;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-4&quot;&gt;&lt;a href=&quot;#cb1-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;        &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; (a &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;IO&lt;/span&gt; c)  &lt;span class=&quot;co&quot;&gt;-- ^ computation to run in-between&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-5&quot;&gt;&lt;a href=&quot;#cb1-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;        &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;IO&lt;/span&gt; c         &lt;span class=&quot;co&quot;&gt;-- returns the value from the in-between computation&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;There are a couple of things you should know when using
&lt;code&gt;bracket&lt;/code&gt;, lest you be surprised by the results.&lt;/p&gt;
&lt;p&gt;First, in some cases the release action may not be called. Or it may
be called but not given a chance to complete.&lt;/p&gt;
&lt;p&gt;Second, the acquire and release action are run with async exception
masked, which may not be what you want.&lt;/p&gt;
&lt;h2 id=&quot;release-guarantee&quot;&gt;Release guarantee&lt;/h2&gt;
&lt;p&gt;It is useful to distinguish two different kinds of resources, let’s
call them “internal” and “external”.&lt;/p&gt;
&lt;p&gt;An example of an internal resource is an &lt;code&gt;MVar&lt;/code&gt; that you
take (acquire) and put back (release):&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb2&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb2-1&quot;&gt;&lt;a href=&quot;#cb2-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;withMVar ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;MVar&lt;/span&gt; a &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; (a &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;IO&lt;/span&gt; b) &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;IO&lt;/span&gt; b&lt;/span&gt;
&lt;span id=&quot;cb2-2&quot;&gt;&lt;a href=&quot;#cb2-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;withMVar m io &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-3&quot;&gt;&lt;a href=&quot;#cb2-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  bracket (takeMVar m) (putMVar m) io&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;An example of an external resource is a directory that you create
(acquire) and remove (release):&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb3&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb3-1&quot;&gt;&lt;a href=&quot;#cb3-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;withFoo ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;IO&lt;/span&gt; a &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;IO&lt;/span&gt; a&lt;/span&gt;
&lt;span id=&quot;cb3-2&quot;&gt;&lt;a href=&quot;#cb3-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;withFoo io &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-3&quot;&gt;&lt;a href=&quot;#cb3-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  bracket_ (createDirectory &lt;span class=&quot;st&quot;&gt;&amp;quot;foo&amp;quot;&lt;/span&gt;) (removeDirectoryRecursive &lt;span class=&quot;st&quot;&gt;&amp;quot;foo&amp;quot;&lt;/span&gt;) io&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The release of an internal resource is noticable only within your
program, and it only matters as long as your program keeps running. If
the program exits, it’s fine not to release an internal resource. An
external resource, on the other hand, always needs to be released.&lt;/p&gt;
&lt;p&gt;It is impossible to guarantee that external resources are always
released. The power may go off, or your program may be terminated with
&lt;code&gt;SIGKILL&lt;/code&gt;, and there won’t be time to clean up.&lt;/p&gt;
&lt;p&gt;Thus, we would like a guarantee that:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;internal resources are released if the program keeps running, to
avoid memory leaks and deadlocks&lt;/li&gt;
&lt;li&gt;external resources are released, assuming the program keeps running
or is terminated in a “civil” way&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Now let’s see why these promises may be broken and what to do about
it.&lt;/p&gt;
&lt;h3 id=&quot;bracket-in-non-main-threads&quot;&gt;&lt;code&gt;bracket&lt;/code&gt; in non-main
threads&lt;/h3&gt;
&lt;p&gt;The main thread is the Haskell thread that executes your
&lt;code&gt;main&lt;/code&gt; function.&lt;/p&gt;
&lt;p&gt;When the main thread finishes, the program finishes, too, without
sending exceptions to other threads and giving them any chance to clean
up.&lt;/p&gt;
&lt;p&gt;Therefore, if your &lt;code&gt;bracket&lt;/code&gt; is executed in some other
thread, its release action may not run when the program terminates.&lt;/p&gt;
&lt;p&gt;This limitation is especially acute in library code, where you don’t
know whether you’re running in the main thread or have any way to tie to
it.&lt;/p&gt;
&lt;p&gt;To avoid this problem, you need to manage your threads. Keep a list
of them (or weak pointers to them, see &lt;code&gt;mkWeakThreadId&lt;/code&gt;), and
give them a heads-up (in the form of an asynchronous exception) before
you exit from &lt;code&gt;main&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;This problem only affects external resources.&lt;/p&gt;
&lt;h3 id=&quot;asynchronous-exceptions&quot;&gt;asynchronous exceptions&lt;/h3&gt;
&lt;p&gt;Even if the release action is called, it may not complete if it is
interrupted by an asynchronous exception.&lt;/p&gt;
&lt;p&gt;A good example is the &lt;code&gt;withTempDirectory&lt;/code&gt; function defined
in the package &lt;code&gt;temporary&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb4&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb4-1&quot;&gt;&lt;a href=&quot;#cb4-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;withTempDirectory targetDir template &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-2&quot;&gt;&lt;a href=&quot;#cb4-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  Exception.bracket&lt;/span&gt;
&lt;span id=&quot;cb4-3&quot;&gt;&lt;a href=&quot;#cb4-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    (liftIO (createTempDirectory targetDir template))&lt;/span&gt;
&lt;span id=&quot;cb4-4&quot;&gt;&lt;a href=&quot;#cb4-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    (liftIO &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt; ignoringIOErrors &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt; removeDirectoryRecursive)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Bit Connor &lt;a
href=&quot;https://github.com/UnkindPartition/temporary/issues/3&quot;&gt;describes
the issue&lt;/a&gt; in detail:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;This function uses &lt;code&gt;bracket&lt;/code&gt; which splits it up into three
stages:&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;“acquire” (create the directory)&lt;/li&gt;
&lt;li&gt;“in-between” (user action)&lt;/li&gt;
&lt;li&gt;“release” (recursively delete the directory)&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Consider the following scenario:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Stage 1 (“acquire”) completes successfully.&lt;/li&gt;
&lt;li&gt;Stage 2 (“user action”) places many files inside the temporary
directory and completes successfully.&lt;/li&gt;
&lt;li&gt;Stage 3 begins: There are many files inside the temporary directory,
and they are deleted one by one. But before they have all been deleted,
an async exception occurs. Even though we are currently in a state of
“masked” async exceptions (thanks to bracket), the individual file
delete operations are “interruptible” and thus our mask will be pierced.
The function will return before all of the temporary files have been
deleted (and of course the temporary directory itself will also
remain).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This is not good. “with-style” functions are expected to guarantee
proper and complete clean up of their resources. And this is not just a
theoretical issue: there is a significant likelihood that the problem
can occur in practice, for example with a program that uses a temporary
directory with many files and the user presses Ctrl-C.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This problem affects both internal and external resources if the
release action includes any interruptible operations.&lt;/p&gt;
&lt;p&gt;To prevent the interruption, wrap the release action in
&lt;code&gt;uninterruptibleMask&lt;/code&gt;.&lt;/p&gt;
&lt;h3 id=&quot;signals&quot;&gt;signals&lt;/h3&gt;
&lt;p&gt;By default, only the &lt;code&gt;SIGINT&lt;/code&gt; signal is turned into a
Haskell exception by the GHC RTS.&lt;/p&gt;
&lt;p&gt;If your process is terminated by any other signal, the release action
won’t run.&lt;/p&gt;
&lt;p&gt;To address this, turn signals into exceptions yourself:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb5&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb5-1&quot;&gt;&lt;a href=&quot;#cb5-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Control.Concurrent&lt;/span&gt; (mkWeakThreadId, myThreadId)&lt;/span&gt;
&lt;span id=&quot;cb5-2&quot;&gt;&lt;a href=&quot;#cb5-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Control.Exception&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;Exception&lt;/span&gt;(..), throwTo)&lt;/span&gt;
&lt;span id=&quot;cb5-3&quot;&gt;&lt;a href=&quot;#cb5-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Control.Monad&lt;/span&gt; (forM_)&lt;/span&gt;
&lt;span id=&quot;cb5-4&quot;&gt;&lt;a href=&quot;#cb5-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Data.Typeable&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;Typeable&lt;/span&gt;)&lt;/span&gt;
&lt;span id=&quot;cb5-5&quot;&gt;&lt;a href=&quot;#cb5-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;System.Posix.Signals&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-6&quot;&gt;&lt;a href=&quot;#cb5-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;System.Mem.Weak&lt;/span&gt; (deRefWeak)&lt;/span&gt;
&lt;span id=&quot;cb5-7&quot;&gt;&lt;a href=&quot;#cb5-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-8&quot;&gt;&lt;a href=&quot;#cb5-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;newtype&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;SignalException&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;SignalException&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Signal&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-9&quot;&gt;&lt;a href=&quot;#cb5-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;deriving&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;Show&lt;/span&gt;, &lt;span class=&quot;dt&quot;&gt;Typeable&lt;/span&gt;)&lt;/span&gt;
&lt;span id=&quot;cb5-10&quot;&gt;&lt;a href=&quot;#cb5-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;instance&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Exception&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;SignalException&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-11&quot;&gt;&lt;a href=&quot;#cb5-11&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-12&quot;&gt;&lt;a href=&quot;#cb5-12&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;installSignalHandlers ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;IO&lt;/span&gt; ()&lt;/span&gt;
&lt;span id=&quot;cb5-13&quot;&gt;&lt;a href=&quot;#cb5-13&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;installSignalHandlers &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-14&quot;&gt;&lt;a href=&quot;#cb5-14&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  main_thread_id &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; myThreadId&lt;/span&gt;
&lt;span id=&quot;cb5-15&quot;&gt;&lt;a href=&quot;#cb5-15&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  weak_tid &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; mkWeakThreadId main_thread_id&lt;/span&gt;
&lt;span id=&quot;cb5-16&quot;&gt;&lt;a href=&quot;#cb5-16&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  forM_ [ sigHUP, sigTERM, sigUSR1, sigUSR2, sigXCPU, sigXFSZ ] &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; \sig &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-17&quot;&gt;&lt;a href=&quot;#cb5-17&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    installHandler sig (&lt;span class=&quot;dt&quot;&gt;Catch&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; send_exception weak_tid sig) &lt;span class=&quot;dt&quot;&gt;Nothing&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-18&quot;&gt;&lt;a href=&quot;#cb5-18&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-19&quot;&gt;&lt;a href=&quot;#cb5-19&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    send_exception weak_tid sig &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-20&quot;&gt;&lt;a href=&quot;#cb5-20&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      m &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; deRefWeak weak_tid&lt;/span&gt;
&lt;span id=&quot;cb5-21&quot;&gt;&lt;a href=&quot;#cb5-21&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;kw&quot;&gt;case&lt;/span&gt; m &lt;span class=&quot;kw&quot;&gt;of&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-22&quot;&gt;&lt;a href=&quot;#cb5-22&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;        &lt;span class=&quot;dt&quot;&gt;Nothing&lt;/span&gt;  &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;return&lt;/span&gt; ()&lt;/span&gt;
&lt;span id=&quot;cb5-23&quot;&gt;&lt;a href=&quot;#cb5-23&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;        &lt;span class=&quot;dt&quot;&gt;Just&lt;/span&gt; tid &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; throwTo tid (toException &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;SignalException&lt;/span&gt; sig)&lt;/span&gt;
&lt;span id=&quot;cb5-24&quot;&gt;&lt;a href=&quot;#cb5-24&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-25&quot;&gt;&lt;a href=&quot;#cb5-25&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;main &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-26&quot;&gt;&lt;a href=&quot;#cb5-26&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  installSignalHandlers&lt;/span&gt;
&lt;span id=&quot;cb5-27&quot;&gt;&lt;a href=&quot;#cb5-27&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;op&quot;&gt;...&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;For the rationale behind this specific collection of signals (which
is far from exhaustive), see &lt;a
href=&quot;https://github.com/UnkindPartition/tasty/pull/268&quot;&gt;this pull
request&lt;/a&gt; by Aleksey Khudyakov.&lt;/p&gt;
&lt;p&gt;This problem only affects external resources. It was pointed out to
me by &lt;a href=&quot;https://github.com/jonboulle&quot;&gt;Jon Boulle&lt;/a&gt; and &lt;a
href=&quot;https://github.com/mands&quot;&gt;Mandeep Gill&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;References:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://ghc.haskell.org/trac/ghc/ticket/10169&quot;&gt;GHC bug
#10169&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://stackoverflow.com/q/18430748/110081&quot;&gt;StackOverflow:
Killing a Haskell binary&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;inadvertent-mask&quot;&gt;Inadvertent mask&lt;/h2&gt;
&lt;p&gt;You could try to write something like&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb6&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb6-1&quot;&gt;&lt;a href=&quot;#cb6-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;main &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-2&quot;&gt;&lt;a href=&quot;#cb6-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  bracket (forkIO myComputation) killThread &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; \_ &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-3&quot;&gt;&lt;a href=&quot;#cb6-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;op&quot;&gt;...&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The idea here is that if &lt;code&gt;main&lt;/code&gt; exits, for whatever
reason, you’ll send an exception to the thread you forked, and give it a
chance to clean up.&lt;/p&gt;
&lt;p&gt;First, this isn’t going to help much because &lt;code&gt;main&lt;/code&gt; will
exit right after &lt;code&gt;killThread&lt;/code&gt;, probably right in the middle
of &lt;code&gt;myComputation&lt;/code&gt;’s cleanup process. Some kind of
synchronisation should be introduced to address this properly. (The
price is that your program may not exit promptly when you interrupt it
with Ctrl-C.)&lt;/p&gt;
&lt;p&gt;There’s another, more subtle issue with the code above. Let’s look at
the definition of &lt;code&gt;bracket&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb7&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb7-1&quot;&gt;&lt;a href=&quot;#cb7-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;bracket before after thing &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb7-2&quot;&gt;&lt;a href=&quot;#cb7-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  mask &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; \restore &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb7-3&quot;&gt;&lt;a href=&quot;#cb7-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    a &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; before&lt;/span&gt;
&lt;span id=&quot;cb7-4&quot;&gt;&lt;a href=&quot;#cb7-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    r &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; restore (thing a) &lt;span class=&quot;ot&quot;&gt;`onException`&lt;/span&gt; after a&lt;/span&gt;
&lt;span id=&quot;cb7-5&quot;&gt;&lt;a href=&quot;#cb7-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    _ &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; after a&lt;/span&gt;
&lt;span id=&quot;cb7-6&quot;&gt;&lt;a href=&quot;#cb7-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;fu&quot;&gt;return&lt;/span&gt; r&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;As you see, the &lt;code&gt;before&lt;/code&gt; action is run in the masked
state. Forked threads inherit the masked state of their parents, so
&lt;code&gt;myComputation&lt;/code&gt; and all threads spawned by it will
unwittingly run in the masked state, unless they do
&lt;code&gt;forkIOWithUnmask&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;In this simple case, you should just use &lt;code&gt;withAsync&lt;/code&gt; from
the async package. What about more complex ones?&lt;/p&gt;
&lt;p&gt;If you do forking explicitly, then you can write
&lt;code&gt;bracket&lt;/code&gt;-like code yourself and restore the forked
computation. Here’s an example of synchronised cleanup:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb8&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb8-1&quot;&gt;&lt;a href=&quot;#cb8-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;main &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb8-2&quot;&gt;&lt;a href=&quot;#cb8-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  cleanupFlag &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; atomically &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; newTVar &lt;span class=&quot;dt&quot;&gt;False&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb8-3&quot;&gt;&lt;a href=&quot;#cb8-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  mask &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; \restore &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb8-4&quot;&gt;&lt;a href=&quot;#cb8-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    pid &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; forkIO &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; restore &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; myComputation cleanupFlag&lt;/span&gt;
&lt;span id=&quot;cb8-5&quot;&gt;&lt;a href=&quot;#cb8-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    restore restOfMain&lt;/span&gt;
&lt;span id=&quot;cb8-6&quot;&gt;&lt;a href=&quot;#cb8-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;ot&quot;&gt;`finally`&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb8-7&quot;&gt;&lt;a href=&quot;#cb8-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;        killThread pid&lt;/span&gt;
&lt;span id=&quot;cb8-8&quot;&gt;&lt;a href=&quot;#cb8-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;        &lt;span class=&quot;co&quot;&gt;-- wait until myComputation finishes its cleanup&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb8-9&quot;&gt;&lt;a href=&quot;#cb8-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;        &lt;span class=&quot;co&quot;&gt;-- and sets the flag to True&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb8-10&quot;&gt;&lt;a href=&quot;#cb8-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;        atomically &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; readTVar cleanupFlag &lt;span class=&quot;op&quot;&gt;&amp;gt;&amp;gt;=&lt;/span&gt; check&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;(You could use an &lt;code&gt;MVar&lt;/code&gt; for synchronisation as well.)&lt;/p&gt;
&lt;p&gt;And what if forking happens inside some library function that you
need to call? In that case, you may want to &lt;code&gt;restore&lt;/code&gt; that
whole function from the beginning.&lt;/p&gt;
</description>
                        <pubDate>Wed, 30 Jul 2014 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2014-07-30-bracket</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2014-07-30-bracket.html</guid>
                </item>
        
                <item>
                        <title>Type-based lift</title>
                        <description>&lt;p&gt;In mtl, the &lt;code&gt;ask&lt;/code&gt; method of the &lt;code&gt;MonadReader&lt;/code&gt;
class will automatically «lift» itself to the topmost
&lt;code&gt;ReaderT&lt;/code&gt; layer in the stack, which is very convenient, but
only works as long as the topmost layer is the one you need. If you have
multiple &lt;code&gt;ReaderT&lt;/code&gt;s in the stack, you often have to insert
manual lifts.&lt;/p&gt;
&lt;p&gt;Previously I &lt;a
href=&quot;/articles/2014-06-11-problem-with-mtl&quot;&gt;described&lt;/a&gt; why a smarter
automatic lifting mechanism is needed to build truly reusable pieces of
monadic code without too much boilerplate.&lt;/p&gt;
&lt;p&gt;In this article I show two ways to achieve a type-based lift (that
is, a lift which takes into account the &lt;code&gt;r&lt;/code&gt; of
&lt;code&gt;ReaderT r&lt;/code&gt;), one relying on
&lt;code&gt;IncoherentInstances&lt;/code&gt;, the other — on closed type
families.&lt;/p&gt;
&lt;!--more--&gt;
&lt;h2 id=&quot;class-based-approach-and-incoherentinstances&quot;&gt;Class-based
approach and IncoherentInstances&lt;/h2&gt;
&lt;p&gt;In &lt;a href=&quot;/articles/2014-06-14-extensible-effects-failed&quot;&gt;Two
failed attempts at extensible effects&lt;/a&gt;, I wrote that simply removing
the fundep from mtl wouldn’t work. This claim was recently disproved by
Ben Foppa and his &lt;a
href=&quot;https://github.com/RobotGymnast/extensible-transformers&quot;&gt;extensible-transformers&lt;/a&gt;
library.&lt;/p&gt;
&lt;p&gt;Why did I think that such an approach wouldn’t work?&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb1&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb1-1&quot;&gt;&lt;a href=&quot;#cb1-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;{-# LANGUAGE MultiParamTypeClasses, FlexibleInstances, OverlappingInstances #-}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-2&quot;&gt;&lt;a href=&quot;#cb1-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Control.Monad.Trans.Reader&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;hiding&lt;/span&gt; (ask)&lt;/span&gt;
&lt;span id=&quot;cb1-3&quot;&gt;&lt;a href=&quot;#cb1-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;qualified&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Control.Monad.Trans.Reader&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Trans&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-4&quot;&gt;&lt;a href=&quot;#cb1-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Control.Monad.Trans.Class&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-5&quot;&gt;&lt;a href=&quot;#cb1-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-6&quot;&gt;&lt;a href=&quot;#cb1-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;MonadReader&lt;/span&gt; r m &lt;span class=&quot;kw&quot;&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-7&quot;&gt;&lt;a href=&quot;#cb1-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;  ask ::&lt;/span&gt; m r&lt;/span&gt;
&lt;span id=&quot;cb1-8&quot;&gt;&lt;a href=&quot;#cb1-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-9&quot;&gt;&lt;a href=&quot;#cb1-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;instance&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Monad&lt;/span&gt; m &lt;span class=&quot;ot&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;MonadReader&lt;/span&gt; r (&lt;span class=&quot;dt&quot;&gt;ReaderT&lt;/span&gt; r m) &lt;span class=&quot;kw&quot;&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-10&quot;&gt;&lt;a href=&quot;#cb1-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  ask &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; Trans.ask&lt;/span&gt;
&lt;span id=&quot;cb1-11&quot;&gt;&lt;a href=&quot;#cb1-11&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-12&quot;&gt;&lt;a href=&quot;#cb1-12&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;instance&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;Monad&lt;/span&gt; m, &lt;span class=&quot;dt&quot;&gt;MonadReader&lt;/span&gt; r m, &lt;span class=&quot;dt&quot;&gt;MonadTrans&lt;/span&gt; t) &lt;span class=&quot;ot&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;MonadReader&lt;/span&gt; r (t m) &lt;span class=&quot;kw&quot;&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-13&quot;&gt;&lt;a href=&quot;#cb1-13&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  ask &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; lift ask&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;GHC, when asked to compile something that uses the above instances,
will ask you in return to enable the &lt;code&gt;IncoherentInstances&lt;/code&gt;
extension. My experience with GHC told me that such a request is just a
polite way for GHC to say «You’re doing something wrong!», so I
immediately dismissed that approach. I had never seen a case where
&lt;code&gt;IncoherentInstances&lt;/code&gt; would be an acceptable solution to the
problem. Well, this one seems to be exactly such a case!&lt;/p&gt;
&lt;p&gt;Switching &lt;code&gt;IncoherentInstances&lt;/code&gt; on here not only makes the
type checker happy, but also makes the code work as expected, at least
in the few tests that I tried.&lt;/p&gt;
&lt;h2 id=&quot;closed-type-classes&quot;&gt;Closed type classes&lt;/h2&gt;
&lt;p&gt;Intuitively, the reason why GHC needs so many ugly extensions to make
the above code work is that we’re trying to simulate a closed type class
with an open one.&lt;/p&gt;
&lt;p&gt;Our type class is essentially a type-level &lt;em&gt;if&lt;/em&gt; operator
comparing two types, and its two instances correspond to the two
branches of the &lt;em&gt;if&lt;/em&gt; operator.&lt;/p&gt;
&lt;p&gt;If only we had closed type classes, we could write&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb2&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb2-1&quot;&gt;&lt;a href=&quot;#cb2-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Control.Monad.Trans.Reader&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;hiding&lt;/span&gt; (ask)&lt;/span&gt;
&lt;span id=&quot;cb2-2&quot;&gt;&lt;a href=&quot;#cb2-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;qualified&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Control.Monad.Trans.Reader&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Trans&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-3&quot;&gt;&lt;a href=&quot;#cb2-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Control.Monad.Trans.Class&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-4&quot;&gt;&lt;a href=&quot;#cb2-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-5&quot;&gt;&lt;a href=&quot;#cb2-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;MonadReader&lt;/span&gt; r m &lt;span class=&quot;kw&quot;&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-6&quot;&gt;&lt;a href=&quot;#cb2-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;  ask ::&lt;/span&gt; m r&lt;/span&gt;
&lt;span id=&quot;cb2-7&quot;&gt;&lt;a href=&quot;#cb2-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-8&quot;&gt;&lt;a href=&quot;#cb2-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;instance&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Monad&lt;/span&gt; m &lt;span class=&quot;ot&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;MonadReader&lt;/span&gt; r (&lt;span class=&quot;dt&quot;&gt;ReaderT&lt;/span&gt; r m) &lt;span class=&quot;kw&quot;&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-9&quot;&gt;&lt;a href=&quot;#cb2-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    ask &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; Trans.ask&lt;/span&gt;
&lt;span id=&quot;cb2-10&quot;&gt;&lt;a href=&quot;#cb2-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-11&quot;&gt;&lt;a href=&quot;#cb2-11&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;instance&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;Monad&lt;/span&gt; m, &lt;span class=&quot;dt&quot;&gt;MonadReader&lt;/span&gt; r m, &lt;span class=&quot;dt&quot;&gt;MonadTrans&lt;/span&gt; t) &lt;span class=&quot;ot&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;MonadReader&lt;/span&gt; r (t m) &lt;span class=&quot;kw&quot;&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-12&quot;&gt;&lt;a href=&quot;#cb2-12&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    ask &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; lift ask&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;(where I put instance declarations inside the class declaration to
show that the class is closed).&lt;/p&gt;
&lt;p&gt;Alas, GHC 7.8 does not have closed type classes, and I have not even
heard of them being developed. All we have is closed type families.
Closed type families would let us compute, say, a type-level number
showing how far we have to &lt;code&gt;lift&lt;/code&gt; a monadic action to reach
the right level. They, however, do not allow us to compute a value-level
witness — the very lifting function!&lt;/p&gt;
&lt;h2 id=&quot;closed-type-families&quot;&gt;Closed type families&lt;/h2&gt;
&lt;p&gt;Still, it is possible to achieve automatic lifting using closed type
families alone. We developed this approach together with Andres Löh at
ZuriHac’14.&lt;/p&gt;
&lt;p&gt;The main idea is to split the problem into two.&lt;/p&gt;
&lt;p&gt;First, we compute the amount of lifting required using a closed type
family&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb3&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb3-1&quot;&gt;&lt;a href=&quot;#cb3-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;co&quot;&gt;-- Peano naturals, promoted to types by DataKinds&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-2&quot;&gt;&lt;a href=&quot;#cb3-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Nat&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Zero&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Suc&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Nat&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-3&quot;&gt;&lt;a href=&quot;#cb3-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-4&quot;&gt;&lt;a href=&quot;#cb3-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;family&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Find&lt;/span&gt; (&lt;span class=&quot;ot&quot;&gt;t ::&lt;/span&gt; (&lt;span class=&quot;op&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;*&lt;/span&gt;) &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; (&lt;span class=&quot;op&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;*&lt;/span&gt;)) (&lt;span class=&quot;ot&quot;&gt;m ::&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;*&lt;/span&gt;)&lt;span class=&quot;ot&quot;&gt; ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Nat&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-5&quot;&gt;&lt;a href=&quot;#cb3-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;dt&quot;&gt;Find&lt;/span&gt; t (t m) &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Zero&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-6&quot;&gt;&lt;a href=&quot;#cb3-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;dt&quot;&gt;Find&lt;/span&gt; t (p m) &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Suc&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;Find&lt;/span&gt; t m)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Second, assuming we know how far to lift, we can compute the lifting
function using an ordinary (open) MPTC:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb4&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb4-1&quot;&gt;&lt;a href=&quot;#cb4-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Monad&lt;/span&gt; m &lt;span class=&quot;ot&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;MonadReaderN&lt;/span&gt; (&lt;span class=&quot;ot&quot;&gt;n ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Nat&lt;/span&gt;) r m &lt;span class=&quot;kw&quot;&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-2&quot;&gt;&lt;a href=&quot;#cb4-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;  askN ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Proxy&lt;/span&gt; n &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; m r&lt;/span&gt;
&lt;span id=&quot;cb4-3&quot;&gt;&lt;a href=&quot;#cb4-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-4&quot;&gt;&lt;a href=&quot;#cb4-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;instance&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Monad&lt;/span&gt; m &lt;span class=&quot;ot&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;MonadReaderN&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Zero&lt;/span&gt; r (&lt;span class=&quot;dt&quot;&gt;ReaderT&lt;/span&gt; r m) &lt;span class=&quot;kw&quot;&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-5&quot;&gt;&lt;a href=&quot;#cb4-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  askN _ &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; Trans.ask&lt;/span&gt;
&lt;span id=&quot;cb4-6&quot;&gt;&lt;a href=&quot;#cb4-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-7&quot;&gt;&lt;a href=&quot;#cb4-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;instance&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;MonadTrans&lt;/span&gt; t, &lt;span class=&quot;dt&quot;&gt;Monad&lt;/span&gt; (t m), &lt;span class=&quot;dt&quot;&gt;MonadReaderN&lt;/span&gt; n r m, &lt;span class=&quot;dt&quot;&gt;Monad&lt;/span&gt; m)&lt;/span&gt;
&lt;span id=&quot;cb4-8&quot;&gt;&lt;a href=&quot;#cb4-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;ot&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;MonadReaderN&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;Suc&lt;/span&gt; n) r (t m)&lt;/span&gt;
&lt;span id=&quot;cb4-9&quot;&gt;&lt;a href=&quot;#cb4-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-10&quot;&gt;&lt;a href=&quot;#cb4-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    askN _ &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; lift &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; askN (&lt;span class=&quot;dt&quot;&gt;Proxy&lt;/span&gt;&lt;span class=&quot;ot&quot;&gt; ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Proxy&lt;/span&gt; n)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;It is important to note that our instances of
&lt;code&gt;MonadReaderN&lt;/code&gt; are non-overlapping. The instance is uniquely
determined by the &lt;code&gt;n :: Nat&lt;/code&gt; type parameter.&lt;/p&gt;
&lt;p&gt;Finally, we glue the two components together to get a nice
&lt;code&gt;ask&lt;/code&gt; function:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb5&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb5-1&quot;&gt;&lt;a href=&quot;#cb5-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;co&quot;&gt;-- Nice constraint alias&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-2&quot;&gt;&lt;a href=&quot;#cb5-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;MonadReader&lt;/span&gt; r m &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;MonadReaderN&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;Find&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;ReaderT&lt;/span&gt; r) m) r m&lt;/span&gt;
&lt;span id=&quot;cb5-3&quot;&gt;&lt;a href=&quot;#cb5-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-4&quot;&gt;&lt;a href=&quot;#cb5-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;ask ::&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;forall&lt;/span&gt; m r &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;MonadReader&lt;/span&gt; r m &lt;span class=&quot;ot&quot;&gt;=&amp;gt;&lt;/span&gt; m r&lt;/span&gt;
&lt;span id=&quot;cb5-5&quot;&gt;&lt;a href=&quot;#cb5-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;ask &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; askN (&lt;span class=&quot;dt&quot;&gt;Proxy&lt;/span&gt;&lt;span class=&quot;ot&quot;&gt; ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Proxy&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;Find&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;ReaderT&lt;/span&gt; r) m))&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;problem-solved&quot;&gt;Problem solved?&lt;/h2&gt;
&lt;p&gt;Not quite. Both solutions described here do abstract from the
position of a monad transformer in the stack, but they do not abstract
from the transformer itself. The &lt;code&gt;MonadReader r&lt;/code&gt; constraint
can only be satisfied with &lt;code&gt;ReaderT r&lt;/code&gt; but not, say
&lt;code&gt;StateT r&lt;/code&gt;. Moreover, a &lt;code&gt;MonadState&lt;/code&gt; constraint,
defined as&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb6&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb6-1&quot;&gt;&lt;a href=&quot;#cb6-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;MonadState&lt;/span&gt; s m &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;MonadStateN&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;Find&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;Control.Monad.State.Lazy.StateT&lt;/span&gt; s) m) s m&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;can only be satisfied by the lazy, but not strict,
&lt;code&gt;StateT&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;I address this issue in the &lt;a
href=&quot;/articles/2014-12-06-abstracting-from-transformer&quot;&gt;subsequent
article&lt;/a&gt;.&lt;/p&gt;
</description>
                        <pubDate>Tue, 15 Jul 2014 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2014-07-15-type-based-lift</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2014-07-15-type-based-lift.html</guid>
                </item>
        
                <item>
                        <title>How to run SQL actions in persistent</title>
                        <description>&lt;p&gt;When I started writing an application that used &lt;a
href=&quot;http://www.yesodweb.com/book/persistent&quot;&gt;persistent&lt;/a&gt; to
interact with a MySQL database, I decided to put the whole application
inside one big &lt;code&gt;SqlPersistM&lt;/code&gt; action, and run it once inside
&lt;code&gt;main&lt;/code&gt;. (To make it clear, this is not a Yesod application; I
simply use persistent as a standalone library.)&lt;/p&gt;
&lt;p&gt;However, as I learned more about persistent and how it worked, it
became clear that this was the wrong way to use persistent. Here’s
why.&lt;/p&gt;
&lt;!--more--&gt;
&lt;h2 id=&quot;problems-of-one-big-sqlpersistm-action&quot;&gt;Problems of one big
&lt;code&gt;SqlPersistM&lt;/code&gt; action&lt;/h2&gt;
&lt;h3 id=&quot;finalizing-transactions&quot;&gt;Finalizing transactions&lt;/h3&gt;
&lt;p&gt;persistent’s SQL layer treats an &lt;code&gt;SqlPersistT&lt;/code&gt; action as a
single transaction. Thus, until you run the action, the transaction is
not committed. Obviously, this is an issue for any long-running server
application.&lt;/p&gt;
&lt;p&gt;You could work around this by calling &lt;code&gt;transactionSave&lt;/code&gt;
manually. Now you have a different but related problem…&lt;/p&gt;
&lt;h3 id=&quot;overlapping-transactions&quot;&gt;Overlapping transactions&lt;/h3&gt;
&lt;p&gt;Normally a single SQL connection can participate in just one SQL
transaction. (There are probably exceptions to this rule which I am not
aware of, but this is how it happens unless you do something
special.)&lt;/p&gt;
&lt;p&gt;Thus, assuming your application is multithreaded, you’ll end up
committing other threads’ transactions that are active at the same
time.&lt;/p&gt;
&lt;p&gt;(Besides, I am not sure whether executing multiple SQL statements
over the same connection simultaneously is supported at all.)&lt;/p&gt;
&lt;h3 id=&quot;resource-deallocation&quot;&gt;Resource deallocation&lt;/h3&gt;
&lt;p&gt;persistent uses resourcet to ensure that resources (such as buffers
that hold result sets) are released as soon as they are not needed.&lt;/p&gt;
&lt;p&gt;resourcet works by handling these two scenarios:&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;No exception is thrown; resources are deallocated by an explicit
&lt;code&gt;release&lt;/code&gt; call.&lt;/li&gt;
&lt;li&gt;An exception is thrown, preventing the &lt;code&gt;release&lt;/code&gt; action
from happening. However, once the exception escapes the enclosing
&lt;code&gt;ResourceT&lt;/code&gt; block, it triggers the exception handler inside
&lt;code&gt;runResourceT&lt;/code&gt;. The exception handler then performs
deallocation.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;When your application consists of one long-running
&lt;code&gt;SqlPersistM&lt;/code&gt; action, chances are you’re catching some
exceptions &lt;em&gt;inside&lt;/em&gt; the &lt;code&gt;ResourceT&lt;/code&gt; block, by the
means of monad-control. Doing that invalidates resourcet’s assumptions:
an exception prevents the &lt;code&gt;release&lt;/code&gt; action from happening,
and yet it never makes it up to &lt;code&gt;runResourceT&lt;/code&gt;, and so your
long-running app leaks resources.&lt;/p&gt;
&lt;h2 id=&quot;do-it-right&quot;&gt;Do it right&lt;/h2&gt;
&lt;p&gt;It implies from the above considerations that the right way to use
&lt;code&gt;persistent&lt;/code&gt; with a SQL backend is:&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;Make &lt;code&gt;SqlPersistT&lt;/code&gt; correspond to logical transactions in
your application.&lt;/li&gt;
&lt;li&gt;Make &lt;code&gt;ResourceT&lt;/code&gt; computations as short-lived as possible.
Ideally, don’t catch exceptions inside &lt;code&gt;ResourceT&lt;/code&gt;; use
&lt;code&gt;finally&lt;/code&gt; instead.&lt;/li&gt;
&lt;li&gt;Use a connection pool.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;disclaimer&quot;&gt;Disclaimer&lt;/h2&gt;
&lt;p&gt;I am not an expert in either persistent or SQL databases; I am in the
process of figuring this out myself. Corrections (and confirmations) are
welcome.&lt;/p&gt;
</description>
                        <pubDate>Mon, 07 Jul 2014 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2014-07-07-persistent</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2014-07-07-persistent.html</guid>
                </item>
        
                <item>
                        <title>Two failed attempts at extensible effects</title>
                        <description>&lt;p&gt;After I had published &lt;a
href=&quot;/articles/2014-06-11-problem-with-mtl&quot;&gt;The problem with mtl&lt;/a&gt;,
many people wondered what my proposed solution was. If you, like them,
are impatient to find out, feel free to peek at the &lt;a
href=&quot;/docs/2014-06-14-extensible-effects.html&quot;&gt;slides&lt;/a&gt; from my &lt;a
href=&quot;http://kievfprog.net/&quot;&gt;kievfprog&lt;/a&gt; talk, or directly at the &lt;a
href=&quot;https://github.com/UnkindPartition/monad-classes&quot;&gt;code on
github&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Still, I’ll continue this series at my own pace. Today we’ll look at
two failed solutions to the problem described in the &lt;a
href=&quot;/articles/2014-06-11-problem-with-mtl&quot;&gt;previous article&lt;/a&gt;.&lt;/p&gt;
&lt;!--more--&gt;
&lt;h2 id=&quot;free-monads&quot;&gt;Free monads&lt;/h2&gt;
&lt;p&gt;The approach based on free monads, proposed in the original &lt;a
href=&quot;http://www.cs.indiana.edu/~sabry/papers/exteff.pdf&quot;&gt;Extensible
Effects&lt;/a&gt; paper by Oleg Kiselyov, Amr Sabry, and Cameron Swords, and
implemented in the &lt;a
href=&quot;http://hackage.haskell.org/package/extensible-effects&quot;&gt;corresponding
package&lt;/a&gt; indeed addresses our problem. My plan for &lt;a
href=&quot;http://www.haskell.org/haskellwiki/ZuriHac2014&quot;&gt;ZuriHac&lt;/a&gt; was to
revise its API and measure and possibly improve its performance.&lt;/p&gt;
&lt;p&gt;I started the hackathon by writing a &lt;a
href=&quot;https://github.com/UnkindPartition/freemonad-benchmark&quot;&gt;benchmark&lt;/a&gt;
to compare different free monad implementations, to decide which one to
use internally in the library.&lt;/p&gt;
&lt;p&gt;The competing free monad implementations were:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Free&lt;/strong&gt;: the standard
&lt;code&gt;Pure a | Free (f (Free f a))&lt;/code&gt; free monad&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Codensity&lt;/strong&gt;:
&lt;code&gt;forall b. (a -&amp;gt; f b) -&amp;gt; f b&lt;/code&gt;, as described in &lt;a
href=&quot;http://www.iai.uni-bonn.de/~jv/mpc08.pdf&quot;&gt;Asymptotic Improvement
of Computations over Free Monads&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Church&lt;/strong&gt;:
&lt;code&gt;forall w. (a -&amp;gt; w) -&amp;gt; (f w -&amp;gt; w) -&amp;gt; w&lt;/code&gt;, as
described in &lt;a
href=&quot;http://comonad.com/reader/2011/free-monads-for-less-2/&quot;&gt;Free
Monads for Less&lt;/a&gt;. This is the Church- (or &lt;a
href=&quot;http://okmij.org/ftp/tagless-final/course/Boehm-Berarducci.html&quot;&gt;Boehm-Berarducci&lt;/a&gt;-)
encoded version of &lt;code&gt;Free&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;NoRemorse&lt;/strong&gt;, as described in &lt;a
href=&quot;http://homepages.cwi.nl/~ploeg/papers/zseq.pdf&quot;&gt;Reflection without
Remorse&lt;/a&gt; (code taken from &lt;a
href=&quot;https://github.com/atzeus/reflectionwithoutremorse&quot;&gt;Atze van der
Ploeg’s repository&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The benchmark compared the performance of &lt;code&gt;State&lt;/code&gt;-like
monads implemented on top of each free monad. I also added a plain
&lt;code&gt;State&lt;/code&gt; from the transformers package to this comparison.&lt;/p&gt;
&lt;p&gt;What surprised me most was not the relative performance of different
representations, but how the &lt;code&gt;State&lt;/code&gt; monad implemented
through free monads did relatively to the &lt;code&gt;State&lt;/code&gt; from
transformers.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/img/freemonad-benchmark.png&quot; /&gt;&lt;/p&gt;
&lt;p&gt;The free monad based &lt;code&gt;State&lt;/code&gt; consistently performed up to
&lt;em&gt;two orders of magnitude&lt;/em&gt; slower than the transformers’ version.
And the free monad version was essentially &lt;code&gt;Free State&lt;/code&gt;, even
without the &lt;code&gt;Typeable&lt;/code&gt;-based open unions (which certainly
carry an overhead of their own).&lt;/p&gt;
&lt;p&gt;Thus, it became clear that if an extensible effects library is to
perform well, it has to be based on raw transformers, not free
monads.&lt;/p&gt;
&lt;h2 id=&quot;mtl&quot;&gt;mtl&lt;/h2&gt;
&lt;p&gt;If, as I wrote in the &lt;a
href=&quot;/articles/2014-06-11-problem-with-mtl&quot;&gt;previous article&lt;/a&gt;, the
functional dependency is an issue in mtl, can we simply get rid of
it?&lt;/p&gt;
&lt;p&gt;Well, we could, but that by itself wouldn’t help much. You see, mtl’s
classes work by having instances that lift, say, &lt;code&gt;MonadState&lt;/code&gt;
actions through &lt;code&gt;ReaderT&lt;/code&gt;, &lt;code&gt;WriterT&lt;/code&gt;, and other
transformers known to mtl:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb1&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb1-1&quot;&gt;&lt;a href=&quot;#cb1-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;instance&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;MonadState&lt;/span&gt; s m &lt;span class=&quot;ot&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;MonadState&lt;/span&gt; s (&lt;span class=&quot;dt&quot;&gt;ReaderT&lt;/span&gt; r m) &lt;span class=&quot;kw&quot;&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-2&quot;&gt;&lt;a href=&quot;#cb1-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    get &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; lift get&lt;/span&gt;
&lt;span id=&quot;cb1-3&quot;&gt;&lt;a href=&quot;#cb1-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    put &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; lift &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt; put&lt;/span&gt;
&lt;span id=&quot;cb1-4&quot;&gt;&lt;a href=&quot;#cb1-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    state &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; lift &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt; state&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;In order to make multiple &lt;code&gt;MonadState&lt;/code&gt; instances work,
we’d have to write a similar instance for lifting
&lt;code&gt;MonadState&lt;/code&gt; through &lt;code&gt;StateT&lt;/code&gt; itself. But in that
case GHC would become confused: it wouldn’t know whether to lift a given
&lt;code&gt;get&lt;/code&gt; through a &lt;code&gt;StateT&lt;/code&gt;, or attempt to execute it
right there. It just isn’t smart enough to make a decision based on the
type of the &lt;code&gt;StateT&lt;/code&gt;’s state.&lt;/p&gt;
&lt;p&gt;My solution to this problem is exactly to teach GHC to make such a
decision. We’ll see how it works in the next article.&lt;/p&gt;
</description>
                        <pubDate>Sat, 14 Jun 2014 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2014-06-14-extensible-effects-failed</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2014-06-14-extensible-effects-failed.html</guid>
                </item>
        
                <item>
                        <title>The problem with mtl</title>
                        <description>&lt;p&gt;This article starts a series in which I am going to publish my
thoughts on and experience with different «extensible effects»
approaches. This one in particular will explain the problem with the
classic mtl approach that motivates us to explore extensible effects in
the first place.&lt;/p&gt;
&lt;!--more--&gt;
&lt;h2 id=&quot;how-transformer-stacks-are-born&quot;&gt;How transformer stacks are
born&lt;/h2&gt;
&lt;p&gt;Often we start with a single monad — perhaps &lt;code&gt;Reader&lt;/code&gt; or
&lt;code&gt;State&lt;/code&gt;. Then we realize it would be nice to add more to it —
other &lt;code&gt;ReaderT&lt;/code&gt;s or &lt;code&gt;StateT&lt;/code&gt;s, probably an
&lt;code&gt;EitherT&lt;/code&gt; etc.&lt;/p&gt;
&lt;p&gt;At that point writing the whole stack in a type signature becomes
rather onerous. So we create a type alias for it, or even a newtype, to
improve type error messages. At first it looks like a good idea — we
have «the monad» for our application. It removes a lot of the cognitive
overhead — all our internal APIs are structured around this monad. The
more time we spend working on our application, the more useful functions
we invent that are automatically compatible and composable; the more joy
it becomes to write code.&lt;/p&gt;
&lt;p&gt;At least this is how I used to structure my code. I learned this
approach from xmonad, the first «serious» Haskell project I studied and
took part in. It has the &lt;code&gt;X&lt;/code&gt; monad, and all the functions
work in and/or with this monad.&lt;/p&gt;
&lt;h2 id=&quot;concrete-stacks-are-too-rigid&quot;&gt;Concrete stacks are too
rigid&lt;/h2&gt;
&lt;p&gt;This approach breaks, however, once we want to have multiple
applications based on the same code. &lt;a href=&quot;http://signalvine.com&quot;&gt;At
work&lt;/a&gt;, for instance, I’d like to reuse a significant part of code
between the real application, the simulator (kind of a REPL for our
messaging campaigns) and tests. But those necessarily use different
monad stacks! The simulator doesn’t deal with MySQL and RabbitMQ
connections; the server doesn’t need to be able to travel back and forth
in time, like our simulator does; and tests for a piece of functionality
should ideally use the smallest stack that’s necessary for that
functionality.&lt;/p&gt;
&lt;p&gt;So we should abstract in some way from the monad stack.&lt;/p&gt;
&lt;h2 id=&quot;mtls-classes&quot;&gt;mtl’s classes&lt;/h2&gt;
&lt;p&gt;One such abstraction comes directly from &lt;code&gt;mtl&lt;/code&gt;, the monad
transformers library.&lt;/p&gt;
&lt;p&gt;If we simply write&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb1&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb1-1&quot;&gt;&lt;a href=&quot;#cb1-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;{-# LANGUAGE NoMonomorphismRestriction #-}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-2&quot;&gt;&lt;a href=&quot;#cb1-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Control.Monad.State&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-3&quot;&gt;&lt;a href=&quot;#cb1-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Control.Monad.Reader&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-4&quot;&gt;&lt;a href=&quot;#cb1-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-5&quot;&gt;&lt;a href=&quot;#cb1-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;foo &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-6&quot;&gt;&lt;a href=&quot;#cb1-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  x &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; ask&lt;/span&gt;
&lt;span id=&quot;cb1-7&quot;&gt;&lt;a href=&quot;#cb1-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  put &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;fromEnum&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;not&lt;/span&gt; x&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;without supplying any type signature, then the inferred type will
be&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb2&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb2-1&quot;&gt;&lt;a href=&quot;#cb2-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;foo ::&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;MonadReader&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Bool&lt;/span&gt; m, &lt;span class=&quot;dt&quot;&gt;MonadState&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Int&lt;/span&gt; m) &lt;span class=&quot;ot&quot;&gt;=&amp;gt;&lt;/span&gt; m ()&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This type signature essentially says that &lt;code&gt;foo&lt;/code&gt; is a
monadic computation which has two effects: reading a boolean value and
reading/writing an integral value. These effects are handled by the
familiar «handlers» &lt;code&gt;runState&lt;/code&gt; and
&lt;code&gt;runReader&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;We can combine any such computations together, and the type system
will automaticaly figure out the total set of effects, in the form of
class constraints. E.g. if we also have&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb3&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb3-1&quot;&gt;&lt;a href=&quot;#cb3-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;bar ::&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;MonadState&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Int&lt;/span&gt; m, &lt;span class=&quot;dt&quot;&gt;MonadWriter&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;All&lt;/span&gt; m) &lt;span class=&quot;ot&quot;&gt;=&amp;gt;&lt;/span&gt; m ()&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;then&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb4&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb4-1&quot;&gt;&lt;a href=&quot;#cb4-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;(&lt;span class=&quot;kw&quot;&gt;do&lt;/span&gt; foo; bar)&lt;span class=&quot;ot&quot;&gt; ::&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;MonadReader&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Bool&lt;/span&gt; m, &lt;span class=&quot;dt&quot;&gt;MonadState&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Int&lt;/span&gt; m, &lt;span class=&quot;dt&quot;&gt;MonadWriter&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;All&lt;/span&gt; m) &lt;span class=&quot;ot&quot;&gt;=&amp;gt;&lt;/span&gt; m ()&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;So it looks like &lt;code&gt;mtl&lt;/code&gt; can provide us with everything that
the «extensible effects» approach promises. Or does it?&lt;/p&gt;
&lt;h2 id=&quot;the-limitation&quot;&gt;The limitation&lt;/h2&gt;
&lt;p&gt;Unfortunately, if we write something a little bit different,
namely&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb5&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb5-1&quot;&gt;&lt;a href=&quot;#cb5-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;{-# LANGUAGE NoMonomorphismRestriction #-}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-2&quot;&gt;&lt;a href=&quot;#cb5-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Control.Monad.State&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-3&quot;&gt;&lt;a href=&quot;#cb5-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Control.Monad.Reader&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-4&quot;&gt;&lt;a href=&quot;#cb5-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-5&quot;&gt;&lt;a href=&quot;#cb5-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;foo &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-6&quot;&gt;&lt;a href=&quot;#cb5-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  x &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; get&lt;/span&gt;
&lt;span id=&quot;cb5-7&quot;&gt;&lt;a href=&quot;#cb5-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  put &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;fromEnum&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;not&lt;/span&gt; x&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;where we’ve changed &lt;code&gt;ask&lt;/code&gt; to &lt;code&gt;get&lt;/code&gt;, the
compiler gets confused:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;test.hs:6:3:
    No instance for (Monad m) arising from a do statement
    Possible fix:
      add (Monad m) to the context of the inferred type of foo :: m ()
    In a stmt of a &amp;#39;do&amp;#39; block: x &amp;lt;- get
    In the expression:
      do { x &amp;lt;- get;
           put $ fromEnum $ not x }
    In an equation for ‘foo’:
        foo
          = do { x &amp;lt;- get;
                 put $ fromEnum $ not x }

test.hs:6:8:
    No instance for (MonadState Bool m) arising from a use of ‘get’
    In a stmt of a &amp;#39;do&amp;#39; block: x &amp;lt;- get
    In the expression:
      do { x &amp;lt;- get;
           put $ fromEnum $ not x }
    In an equation for ‘foo’:
        foo
          = do { x &amp;lt;- get;
                 put $ fromEnum $ not x }

test.hs:7:3:
    No instance for (MonadState Int m) arising from a use of ‘put’
    In the expression: put
    In a stmt of a &amp;#39;do&amp;#39; block: put $ fromEnum $ not x
    In the expression:
      do { x &amp;lt;- get;
           put $ fromEnum $ not x }&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is because mtl asserts, via a mechanism called functional
dependency, that a monadic stack can have only once instance of
&lt;code&gt;MonadState&lt;/code&gt;. Because &lt;code&gt;get&lt;/code&gt; and &lt;code&gt;put&lt;/code&gt;
in the above example operate with different types of state, that code is
invalid.&lt;/p&gt;
&lt;h2 id=&quot;merging-transformer-layers&quot;&gt;Merging transformer layers&lt;/h2&gt;
&lt;p&gt;Since we can’t have multiple different &lt;code&gt;MonadState&lt;/code&gt;
constraints for our reusable monadic computation, we need to merge all
&lt;code&gt;StateT&lt;/code&gt; layers in order to be able to access them through
the &lt;code&gt;MonadState&lt;/code&gt; class:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb7&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb7-1&quot;&gt;&lt;a href=&quot;#cb7-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;MyState&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;MyState&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb7-2&quot;&gt;&lt;a href=&quot;#cb7-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  {&lt;span class=&quot;ot&quot;&gt; _sInt ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Int&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb7-3&quot;&gt;&lt;a href=&quot;#cb7-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  ,&lt;span class=&quot;ot&quot;&gt; _sBool ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Bool&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb7-4&quot;&gt;&lt;a href=&quot;#cb7-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  }&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Then we could generate lenses and put them in a class to achieve
modularity:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb8&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb8-1&quot;&gt;&lt;a href=&quot;#cb8-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Has&lt;/span&gt; f t &lt;span class=&quot;kw&quot;&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb8-2&quot;&gt;&lt;a href=&quot;#cb8-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;  hasLens ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Lens&lt;/span&gt; t f&lt;/span&gt;
&lt;span id=&quot;cb8-3&quot;&gt;&lt;a href=&quot;#cb8-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb8-4&quot;&gt;&lt;a href=&quot;#cb8-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;foo ::&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;MonadState&lt;/span&gt; s m, &lt;span class=&quot;dt&quot;&gt;Has&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Int&lt;/span&gt; s, &lt;span class=&quot;dt&quot;&gt;Has&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Bool&lt;/span&gt; s) &lt;span class=&quot;ot&quot;&gt;=&amp;gt;&lt;/span&gt; m ()&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The drawbacks of this approach are:&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;It is boilerplate-heavy, requiring an instance per field and a
record per stack. When you need to convert between these records, it can
be quite annoying.&lt;/li&gt;
&lt;li&gt;Since monad transformers don’t commute in general, you can’t always
merge two &lt;code&gt;StateT&lt;/code&gt; layers together. For instance, there’s no
way to achieve the semantics of
&lt;code&gt;StateT s1 (MaybeT (StateT s2 Identity))&lt;/code&gt; using only one
layer of &lt;code&gt;StateT&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;mtl’s classes almost provide a valid «extensible effects»
implementation, if not for the functional dependency that lets us have
only single &lt;code&gt;MonadState&lt;/code&gt; instance per stack.&lt;/p&gt;
&lt;p&gt;In the &lt;a href=&quot;/articles/2014-07-15-type-based-lift&quot;&gt;subsequent
article&lt;/a&gt; we’ll explore ways to address this limitation.&lt;/p&gt;
</description>
                        <pubDate>Wed, 11 Jun 2014 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2014-06-11-problem-with-mtl</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2014-06-11-problem-with-mtl.html</guid>
                </item>
        
                <item>
                        <title>Avoid equational function definitions</title>
                        <description>&lt;p&gt;One of the first things that Haskell beginners usually notice is that
Haskell has this somewhat unusual but attractive way of defining
functions case-by-case:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb1&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb1-1&quot;&gt;&lt;a href=&quot;#cb1-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;fu&quot;&gt;foldr&lt;/span&gt; f z []     &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; z &lt;/span&gt;
&lt;span id=&quot;cb1-2&quot;&gt;&lt;a href=&quot;#cb1-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;fu&quot;&gt;foldr&lt;/span&gt; f z (x&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt;xs) &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; f x (&lt;span class=&quot;fu&quot;&gt;foldr&lt;/span&gt; f z xs) &lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;It looks fun and math-y. The other way to do pattern matching,
&lt;code&gt;case&lt;/code&gt; expressions, is much less advertized, probably because
&lt;code&gt;case&lt;/code&gt; invokes associations with dirty old imperative
programming. Here’s how the same function could be defined using
&lt;code&gt;case&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb2&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb2-1&quot;&gt;&lt;a href=&quot;#cb2-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;fu&quot;&gt;foldr&lt;/span&gt; f z l &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-2&quot;&gt;&lt;a href=&quot;#cb2-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;case&lt;/span&gt; l &lt;span class=&quot;kw&quot;&gt;of&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-3&quot;&gt;&lt;a href=&quot;#cb2-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    []   &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; z &lt;/span&gt;
&lt;span id=&quot;cb2-4&quot;&gt;&lt;a href=&quot;#cb2-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    x&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt;xs &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; f x (&lt;span class=&quot;fu&quot;&gt;foldr&lt;/span&gt; f z xs) &lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;However, there are plenty of reasons to prefer &lt;code&gt;case&lt;/code&gt; to
multiple function definition clauses.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;(If some of these look insignificant at first sight, think of a
datatype with tens of constructors, which is quite common when working
with abstract syntax trees.)&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;&lt;p&gt;&lt;abbr title=&quot;Don&apos;t repeat yourself&quot;&gt;&lt;strong&gt;DRY&lt;/strong&gt;&lt;/abbr&gt;.
Notice how in the equational style the function name and argument names
get repeated.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;It makes it clear what the function decides upon. The equational
style allows you to pattern match on different arguments in different
clauses, or even on multiple arguments in the same clause:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb3&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb3-1&quot;&gt;&lt;a href=&quot;#cb3-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;f [] &lt;span class=&quot;dv&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;0&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-2&quot;&gt;&lt;a href=&quot;#cb3-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;f _  &lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-3&quot;&gt;&lt;a href=&quot;#cb3-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;f _  _ &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;2&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;It gives more power, but also makes it harder to see what’s going on.
More importantly, even when this additional power is &lt;em&gt;not&lt;/em&gt; used,
it’s not obvious from the code itself until you eye-scan all the
clauses.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;It makes code easier to modify or refactor. Tasks like&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;adding or removing a function argument&lt;/li&gt;
&lt;li&gt;introducing a local definition common for multiple cases&lt;/li&gt;
&lt;li&gt;preprocessing function arguments or post-processing the function
result&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;are trivial with the &lt;code&gt;case&lt;/code&gt; expression, and hard to
impossible (without rewriting or introducing other top-level functions)
with clauses.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;When profiling, you often want to add an &lt;code&gt;{-# SCC #-}&lt;/code&gt;
pragma for a function. If the function is written using multiple cases,
you need to attach this pragma to every clause separately. Moreover,
even if you do so, they won’t account for the evaluation of arguments
due to pattern matching in left-hand sides of the equations.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Once you start reading the Core or STG code, writing functions
using &lt;code&gt;case&lt;/code&gt; makes it much easier to follow the connection
between the original source and its intermediate
representation.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Perhaps the only reason to have multiple clauses is if you need that
additional power of matching on several arguments at the same time,
e.g.&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb4&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb4-1&quot;&gt;&lt;a href=&quot;#cb4-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;dt&quot;&gt;Right&lt;/span&gt; a &lt;span class=&quot;op&quot;&gt;&amp;lt;*&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Right&lt;/span&gt; b &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Right&lt;/span&gt; (a b)&lt;/span&gt;
&lt;span id=&quot;cb4-2&quot;&gt;&lt;a href=&quot;#cb4-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;dt&quot;&gt;Left&lt;/span&gt;  a &lt;span class=&quot;op&quot;&gt;&amp;lt;*&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Right&lt;/span&gt; _ &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Left&lt;/span&gt; a&lt;/span&gt;
&lt;span id=&quot;cb4-3&quot;&gt;&lt;a href=&quot;#cb4-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;dt&quot;&gt;Right&lt;/span&gt; _ &lt;span class=&quot;op&quot;&gt;&amp;lt;*&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Left&lt;/span&gt; b  &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Left&lt;/span&gt; b&lt;/span&gt;
&lt;span id=&quot;cb4-4&quot;&gt;&lt;a href=&quot;#cb4-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;dt&quot;&gt;Left&lt;/span&gt;  a &lt;span class=&quot;op&quot;&gt;&amp;lt;*&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Left&lt;/span&gt; b  &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Left&lt;/span&gt; (a &lt;span class=&quot;op&quot;&gt;&amp;lt;&amp;gt;&lt;/span&gt; b)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;You could do this with &lt;code&gt;case&lt;/code&gt; by matching on tuples, but
it isn’t as nice.&lt;/p&gt;
&lt;p&gt;Other than this, I rarely ever define functions in the equational
style in my code.&lt;/p&gt;
</description>
                        <pubDate>Fri, 09 May 2014 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2014-05-09-clauses</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2014-05-09-clauses.html</guid>
                </item>
        
                <item>
                        <title>Lens is unidiomatic Haskell</title>
                        <description>&lt;p&gt;Edward Kmett &lt;a
href=&quot;http://www.reddit.com/r/haskell/comments/23q8kc/wreq_a_capable_new_http_client_library/ch02tf8&quot;&gt;writes&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Ironically if I had to say anything from the traffic in my inbox and
on #haskell about it, it is mostly the old guard who gets disgruntled by
lens.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;So let me try and explain why that is. I’ll go ahead and say this:
&lt;em&gt;&lt;code&gt;lens&lt;/code&gt; is unidiomatic Haskell&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;By which I mean that &lt;code&gt;lens&lt;/code&gt; isn’t like any other library
that we normally use. It doesn’t follow the conventions of Haskell APIs,
on which I elaborate below.&lt;/p&gt;
&lt;!--more--&gt;
&lt;div style=&quot;text-align:center;&quot;&gt;
&lt;p&gt;&lt;img src=&quot;/ccc/images/lens.png&quot; width=&quot;700&quot;&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Now let me clarify that this doesn’t necessarily mean that
&lt;code&gt;lens&lt;/code&gt; is a bad library. It’s an &lt;em&gt;unusual&lt;/em&gt; library.
It’s almost a separate language, with its own idioms, embedded in
Haskell.&lt;/p&gt;
&lt;p&gt;It is as unusual as, say, Yesod is. But unlike Yesod, which follows
Haskell’s spirit, not letter (syntax), &lt;code&gt;lens&lt;/code&gt;, I argue,
follows Haskell’s letter, but not its spirit.&lt;/p&gt;
&lt;p&gt;So here’s why I think &lt;code&gt;lens&lt;/code&gt; violates the spirit of
Haskell:&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;&lt;p&gt;In Haskell, types provide a pretty good explanation of what a
function does. Good luck deciphering &lt;code&gt;lens&lt;/code&gt; types.&lt;/p&gt;
&lt;p&gt;Here’s a random function signature I picked from
&lt;code&gt;lens&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb1&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb1-1&quot;&gt;&lt;a href=&quot;#cb1-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;below ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Traversable&lt;/span&gt; f &lt;span class=&quot;ot&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;APrism&amp;#39;&lt;/span&gt; s a &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Prism&amp;#39;&lt;/span&gt; (f s) (f a)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Despite having some (fairly basic) understanding of what prisms are,
this signature tells me nothing at all.&lt;/p&gt;
&lt;p&gt;So you have to rely on documentation much more than on types. Yeah,
just like in Ruby.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Usually, types in Haskell are rigid. This leads to a distinctive
style of composing programs: look at the types and see what fits where.
This is impossible with &lt;code&gt;lens&lt;/code&gt;, which takes overloading to
the level mainstream Haskell probably hasn’t seen before.&lt;/p&gt;
&lt;p&gt;We have to learn the new language of the &lt;code&gt;lens&lt;/code&gt;
combinators and how to compose them, instead of enjoying our knowledge
of how to compose Haskell functions. Formally, &lt;code&gt;lens&lt;/code&gt; types
&lt;em&gt;are&lt;/em&gt; Haskell function types, but while with ordinary Haskell
functions you immediately see from types whether they can be composed,
with &lt;code&gt;lens&lt;/code&gt; functions this is very hard in practice.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The size of the &lt;code&gt;lens&lt;/code&gt; API is comparable to the size
of what I’d call «core Haskell» (i.e. more or less the &lt;code&gt;base&lt;/code&gt;
library). It is also similar in spirit to &lt;code&gt;base&lt;/code&gt;: it has a
big number of trivial combinations of basic functions, in order to
create a base vocabulary in which bigger programs are expressed.&lt;/p&gt;
&lt;p&gt;Ordinary libraries, instead, give only basic functions/combinators,
and rely on the vocabulary provided by &lt;code&gt;base&lt;/code&gt; (or
&lt;code&gt;lens&lt;/code&gt;) to compose them together.&lt;/p&gt;
&lt;p&gt;This is why I regard &lt;code&gt;lens&lt;/code&gt; as a language in its own. And
this demonstrates why learning &lt;code&gt;lens&lt;/code&gt; is hard: surely
learning a new language is harder than learning a new library.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Dependencies. A library as basic in its purpose as
&lt;code&gt;lens&lt;/code&gt; ideally should have almost no dependencies at all.
Instead, other libraries should depend on it and implement its
interface. (Or even do it without depending on it, as is possible with
&lt;code&gt;lens&lt;/code&gt;.)&lt;/p&gt;
&lt;p&gt;A package implementing lenses that depends on a JSON parsing library
and a gzip compression library sounds almost like a joke to me.&lt;/p&gt;
&lt;p&gt;OTOH, it kind of makes sense if you think about &lt;code&gt;lens&lt;/code&gt; as
a language. It just ships with a “rich standard library”. Nice!&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Backward composition of lenses. It’s a minor issue, and I
wouldn’t mention it if it wasn’t a great demonstration of how
&lt;code&gt;lens&lt;/code&gt; goes against the conventions of Haskell.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Note that I’m not trying to make a judgment here (although my tone
probably does give away my attitude towards &lt;code&gt;lens&lt;/code&gt;). I’m
simply explaining why people may dislike and resist it.&lt;/p&gt;
&lt;p&gt;Nor am I trying to argue against any particular design decision of
&lt;code&gt;lens&lt;/code&gt;. I’m sure they all have valid rationale behind
them.&lt;/p&gt;
&lt;p&gt;I just hope that someone will write an idiomatic Haskell library as
powerful as (or close to) &lt;code&gt;lens&lt;/code&gt;, with perhaps a different
set of compromises made. Otherwise, I’m afraid we all will have to learn
this new language sooner or later.&lt;/p&gt;
</description>
                        <pubDate>Thu, 24 Apr 2014 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2014-04-24-lens-unidiomatic</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2014-04-24-lens-unidiomatic.html</guid>
                </item>
        
                <item>
                        <title>Setting up Samsung Wireless Printer on Linux</title>
                        <description>&lt;p&gt;Here’s a complete guide for setting up a wireless Samsung printer on
Linux, where by “setting up” I mean making it connect to your wireless
network.&lt;/p&gt;
&lt;p&gt;It worked for me with &lt;a
href=&quot;https://www.samsung.com/ca/consumer/office/printer-multifunction/monochrome-laser/ML-2165W/XAA&quot;&gt;Samsung
ML-2165W&lt;/a&gt; on Debian GNU/Linux «jessie», but should work for other
models and distributions, too.&lt;/p&gt;
&lt;!--more--&gt;
&lt;h2 id=&quot;connecting-samsung-printer-to-a-wireless-network&quot;&gt;Connecting
Samsung printer to a wireless network&lt;/h2&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;&lt;p&gt;Create a new, temporary user. We’ll use it to launch Samsung’s
wireless setup utility. This is optional, but it provides an additional
layer of security (who knows what those utilities from Samsung do behind
the scenes) and ensures that nothing will mess with your system.&lt;/p&gt;
&lt;p&gt;We add the new user to the &lt;code&gt;lp&lt;/code&gt; group, so that it can talk
to the printer.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt; user$ sudo useradd --create-home --shell /bin/bash --groups lp samsung&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Allow the new user to use our display. (Samsung’s utility is
graphical.)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt; user$ xhost +local:samsung&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Now, time to switch to our temporary user.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt; user$ sudo -E su samsung&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Download Samsung’s PSU (“Printer Settings Utility”) archive from
their website. Unpack it and go to the &lt;code&gt;wirelesssetup&lt;/code&gt;
directory.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt; samsung$ wget http://downloadcenter.samsung.com/content/DR/201110/20111019151150392/PSU_1.01.tar.gz
 samsung$ tar xzf PSU_1.01.tar.gz
 samsung$ cd cdroot/Linux/wirelesssetup&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;(If Samsung’s link doesn’t work, &lt;a
href=&quot;/files/2014-04-21-wireless-samsung-printer-linux/PSU_1.01.tar.gz&quot;&gt;here&lt;/a&gt;
is a backup of that archive.)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Check if there are any missing dynamic libraries:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt; samsung$ ldd bin64/wirelesssetup  | grep &amp;#39;not found&amp;#39;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;(Note: this is for a 64-bit system. On a 32-bit system, replace
&lt;code&gt;bin64&lt;/code&gt; with &lt;code&gt;bin&lt;/code&gt;.)&lt;/p&gt;
&lt;p&gt;In my case, the output was&lt;/p&gt;
&lt;pre&gt;&lt;code&gt; libnetsnmp.so.10 =&amp;gt; not found&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This particular library is included in the PSU archive, so we load it
by&lt;/p&gt;
&lt;pre&gt;&lt;code&gt; samsung$ export LD_PRELOAD=$PWD/../psu/share/lib64/libnetsnmp.so.10.0.2&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;(Likewise, replace &lt;code&gt;lib64&lt;/code&gt; with &lt;code&gt;lib&lt;/code&gt; on a
32-bit system.)&lt;/p&gt;
&lt;p&gt;If there are more missing libraries, first see if your distribution
ships them. The major versions must match! E.g. Debian jessie ships
&lt;code&gt;libnetsnmp.so.30.0.2&lt;/code&gt;, which has the major version number
30, so that won’t do.&lt;/p&gt;
&lt;p&gt;If &lt;code&gt;libstdc++.so.5&lt;/code&gt; is missing, it may be provided by a
compatibility package (e.g. &lt;code&gt;compat-libstdc++-33&lt;/code&gt; on Fedora
26).&lt;/p&gt;
&lt;p&gt;If your distribution doesn’t have the right version, use a resource
like &lt;a href=&quot;http://rpm.pbone.net/&quot;
class=&quot;uri&quot;&gt;http://rpm.pbone.net/&lt;/a&gt; to find a package that has one.
Unpack it (do not install!) and set &lt;code&gt;LD_PRELOAD&lt;/code&gt; and/or
&lt;code&gt;LD_LIBRARY_PATH&lt;/code&gt; so that they are found.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Now connect the printer via a USB cable to the Linux machine and
run&lt;/p&gt;
&lt;pre&gt;&lt;code&gt; samsung$ bin64/wirelesssetup /dev/usb/lp0&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;A graphical window should appear, where you’ll be able to choose your
wireless network and enter the password to it.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;After you made the printer connect to the wireless network, you
can logout and remove the temporary user. Note that the command below
will remove that user’s home directory.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt; user$ sudo userdel --remove samsung&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;configuring-the-printer&quot;&gt;Configuring the printer&lt;/h2&gt;
&lt;p&gt;&lt;a
href=&quot;/files/2014-04-21-wireless-samsung-printer-linux/Samsung_Wireless_Printer.ppd&quot;&gt;This
PPD file&lt;/a&gt; worked well for me with this printer model.&lt;/p&gt;
</description>
                        <pubDate>Mon, 21 Apr 2014 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2014-04-21-wireless-samsung-printer-linux</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2014-04-21-wireless-samsung-printer-linux.html</guid>
                </item>
        
                <item>
                        <title>JSON validation combinators</title>
                        <description>&lt;p&gt;At &lt;a href=&quot;http://signalvine.com&quot;&gt;Signal Vine&lt;/a&gt; we have a
JSON-based language for describing text messaging campaigns. We may
design a better surface syntax for this language in the future, but the
current one gets the job done and there are certain existing systems
that depend on it.&lt;/p&gt;
&lt;p&gt;Anyway, the problem with this language is that it is too easy to make
mistakes — including errors in JSON syntax, structural errors (plugging
an array where an object is expected), or name errors (making a typo in
a field name).&lt;/p&gt;
&lt;p&gt;So the first thing I did was write a validator for our JSON
format.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;There are several projects of «JSON schemas» around, but there were
many reasons against using them.&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;&lt;p&gt;I don’t know about the quality of the tools that support such
schemas (i.e. the quality of error messages they generate), and the
expressivity of the schemas themselves (whether they’d let us to express
the structure of our JSON structure and the constraints we’d like to
enforce). So, though it may seem that using an existing solution is
«free», it is not — I’d have to spend time learning and evaluating these
existing solutions.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;I remember that we went through this in our team at Barclays, and
eventually decided to create a custom JSON schema language, although I
was not involved in the evaluation process, so can’t share the
details.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;I was almost certain that no existing «generic JSON schema»
solution can provide the power of a custom one. For instance, some of
the JSON strings contain expressions in another in-house mini-language.
Ideally, I’d like to parse those expressions while I am parsing the
enclosing JSON structure, and give locations of possible errors as they
appear in the JSON file.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;I’d need a parser for the language anyway. Maintaining a schema
separately from the parser would mean one more thing to keep in sync and
worry about.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;I couldn’t use an existing JSON parsing library either. Of course,
&lt;code&gt;aeson&lt;/code&gt; was out of question, being notorious for its poor
error messages (since it’s based on &lt;code&gt;attoparsec&lt;/code&gt; and
optimized for speed). &lt;code&gt;json&lt;/code&gt;, though, is based on
&lt;code&gt;parsec&lt;/code&gt;, so its error messages are better.&lt;/p&gt;
&lt;p&gt;But there is a deeper reason why a JSON parsing library is inadequate
for validation. All of the existing JSON libraries first parse into a
generic JSON structure, and only then do they try to recognize the
specific format and convert to a value of the target Haskell type.&lt;/p&gt;
&lt;p&gt;Which means that during parsing, only JSON syntax errors will be
detected, but not the other kinds of errors described above. Granted,
they all can be detected sooner or later. But what differentiates sooner
from later is that once we’re out of the parsing monad, we no longer
have access to the position information (unless, of course, our JSON
parsing library does extra work to store locations in the parsed JSON
structure — which it typically doesn’t). And not having such position
information severely impacts our ability to produce good error
messages.&lt;/p&gt;
&lt;p&gt;To summarize, in order to provide good diagnostics, it is important
to parse exactly the language we expect (and not some superset thereof),
and to perform all the checks in the parsing monad, where we have access
to location information.&lt;/p&gt;
&lt;h2 id=&quot;json-parsing-combinators&quot;&gt;JSON parsing combinators&lt;/h2&gt;
&lt;p&gt;Even though I couldn’t re-use an existing JSON parser or schema, I
still wanted my parser to be high-level, and ideally to resemble a JSON
schema, just embedded in Haskell.&lt;/p&gt;
&lt;p&gt;The rest of this article describes the JSON schema combinators I
wrote for this purpose.&lt;/p&gt;
&lt;h3 id=&quot;strings&quot;&gt;Strings&lt;/h3&gt;
&lt;p&gt;As I mentioned before, the &lt;code&gt;json&lt;/code&gt; package uses
&lt;code&gt;parsec&lt;/code&gt; underneath, so I was able to reuse some basic
definitions from there — most notably, &lt;code&gt;p_string&lt;/code&gt;, which
parses a JSON string. This is fortunate, because handling escape
sequences is not straightforward, and I’d rather use a well-tested
existing implementation.&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb1&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb1-1&quot;&gt;&lt;a href=&quot;#cb1-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;string ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Parser&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;String&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-2&quot;&gt;&lt;a href=&quot;#cb1-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;string &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;co&quot;&gt;{- copied from Text.JSON.Parsec -}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;I introduced one other combinator, &lt;code&gt;theString&lt;/code&gt;, which
parses a given string:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb2&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb2-1&quot;&gt;&lt;a href=&quot;#cb2-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;theString ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Parser&lt;/span&gt; ()&lt;/span&gt;
&lt;span id=&quot;cb2-2&quot;&gt;&lt;a href=&quot;#cb2-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;theString str &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; (&lt;span class=&quot;op&quot;&gt;&amp;lt;?&amp;gt;&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;quot;\&amp;quot;&amp;quot;&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;++&lt;/span&gt; str &lt;span class=&quot;op&quot;&gt;++&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;quot;\&amp;quot;&amp;quot;&lt;/span&gt;) &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; try &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-3&quot;&gt;&lt;a href=&quot;#cb2-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  str&amp;#39; &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; string&lt;/span&gt;
&lt;span id=&quot;cb2-4&quot;&gt;&lt;a href=&quot;#cb2-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;if&lt;/span&gt; str &lt;span class=&quot;op&quot;&gt;==&lt;/span&gt; str&amp;#39;&lt;/span&gt;
&lt;span id=&quot;cb2-5&quot;&gt;&lt;a href=&quot;#cb2-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;kw&quot;&gt;then&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;return&lt;/span&gt; ()&lt;/span&gt;
&lt;span id=&quot;cb2-6&quot;&gt;&lt;a href=&quot;#cb2-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;kw&quot;&gt;else&lt;/span&gt; empty&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;objects&quot;&gt;Objects&lt;/h3&gt;
&lt;p&gt;Objects are an interesting case because we know what set of fields to
expect, but not the order in which they come (it may be arbitrary). Such
syntax is known as a «permutation phrase», and can be parsed as
described in the classical paper &lt;a
href=&quot;http://www.cs.uu.nl/wiki/pub/USCS/InterestingPapers/PermutationsJFP.pdf&quot;&gt;Parsing
Permutation Phrases&lt;/a&gt; by Arthur Baars, Andres Löh and Doaitse
Swierstra.&lt;/p&gt;
&lt;p&gt;There are surprisingly many implementations of permutation parsing on
hackage, including one in &lt;code&gt;parsec&lt;/code&gt; itself. Most of them
suffer from one or both of the following issues:&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;&lt;p&gt;they use custom combinators, which, despite being similar to
&lt;code&gt;Applicative&lt;/code&gt; and &lt;code&gt;Alternative&lt;/code&gt; operators, have
their quirks and require learning&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;they don’t support permutation phrases with separators, which is
obviously required to parse JSON objects. (The technique to parse
permutation phrases with separators was descibed in the original paper,
too.)&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;On the other hand, the &lt;a
href=&quot;http://hackage.haskell.org/package/action-permutations&quot;&gt;&lt;code&gt;action-permutations&lt;/code&gt;&lt;/a&gt;
library by Ross Paterson addresses both of these issues. It provides the
familiar &lt;code&gt;Applicative&lt;/code&gt; interface to combine permutation
elements (or atoms, as it calls them), and includes the function
&lt;code&gt;runPermsSep&lt;/code&gt; to parse phrases with separators. The interface
is also very generic, requiring the underlying functor to be just
&lt;code&gt;Alternative&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Below are the combinators for parsing JSON objects.
&lt;code&gt;field&lt;/code&gt; parses a single object field (or &lt;em&gt;member&lt;/em&gt;, as
it’s called in the JSON spec), using the supplied parser to parse the
field’s value. &lt;code&gt;optField&lt;/code&gt; is similar, except it returns
&lt;code&gt;Nothing&lt;/code&gt; if the field is absent (in which case
&lt;code&gt;field&lt;/code&gt; would produce an error message). Finally,
&lt;code&gt;theField&lt;/code&gt; is a shortcut to parse a field with the fixed
contents. It is useful when there’s a tag-like field identifying the
type/class of the object, for instance&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb3&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb3-1&quot;&gt;&lt;a href=&quot;#cb3-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Item&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-2&quot;&gt;&lt;a href=&quot;#cb3-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Book&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-3&quot;&gt;&lt;a href=&quot;#cb3-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;dt&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;co&quot;&gt;-- writer&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-4&quot;&gt;&lt;a href=&quot;#cb3-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;op&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Song&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-5&quot;&gt;&lt;a href=&quot;#cb3-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;dt&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;co&quot;&gt;-- composer&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-6&quot;&gt;&lt;a href=&quot;#cb3-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;dt&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;co&quot;&gt;-- singer&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-7&quot;&gt;&lt;a href=&quot;#cb3-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-8&quot;&gt;&lt;a href=&quot;#cb3-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;item &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-9&quot;&gt;&lt;a href=&quot;#cb3-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  (try &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt; object &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-10&quot;&gt;&lt;a href=&quot;#cb3-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;dt&quot;&gt;Book&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;&amp;lt;$&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-11&quot;&gt;&lt;a href=&quot;#cb3-11&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    theField &lt;span class=&quot;st&quot;&gt;&amp;quot;type&amp;quot;&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;quot;book&amp;quot;&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;&amp;lt;*&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-12&quot;&gt;&lt;a href=&quot;#cb3-12&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    field &lt;span class=&quot;st&quot;&gt;&amp;quot;writer&amp;quot;&lt;/span&gt; string)&lt;/span&gt;
&lt;span id=&quot;cb3-13&quot;&gt;&lt;a href=&quot;#cb3-13&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;op&quot;&gt;&amp;lt;|&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-14&quot;&gt;&lt;a href=&quot;#cb3-14&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  (try &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt; object &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-15&quot;&gt;&lt;a href=&quot;#cb3-15&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;dt&quot;&gt;Song&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;&amp;lt;$&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-16&quot;&gt;&lt;a href=&quot;#cb3-16&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    theField &lt;span class=&quot;st&quot;&gt;&amp;quot;type&amp;quot;&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;quot;song&amp;quot;&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;&amp;lt;*&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-17&quot;&gt;&lt;a href=&quot;#cb3-17&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    field &lt;span class=&quot;st&quot;&gt;&amp;quot;composer&amp;quot;&lt;/span&gt; string &lt;span class=&quot;op&quot;&gt;&amp;lt;*&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-18&quot;&gt;&lt;a href=&quot;#cb3-18&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    field &lt;span class=&quot;st&quot;&gt;&amp;quot;singer&amp;quot;&lt;/span&gt; string)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;(Note: examples in this article have nothing to do with the JSON
schema we actually use at Signal Vine.)&lt;/p&gt;
&lt;p&gt;One thing to pay attention to is how field parsers
(&lt;code&gt;field&lt;/code&gt;, &lt;code&gt;theField&lt;/code&gt; and &lt;code&gt;optField&lt;/code&gt;)
have a different type from the ordinary parsers. This makes it much
easier to reason about what actually gets permuted.&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb4&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb4-1&quot;&gt;&lt;a href=&quot;#cb4-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;object ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Perms&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Parser&lt;/span&gt; a &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Parser&lt;/span&gt; a&lt;/span&gt;
&lt;span id=&quot;cb4-2&quot;&gt;&lt;a href=&quot;#cb4-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;object fields &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; (&lt;span class=&quot;op&quot;&gt;&amp;lt;?&amp;gt;&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;quot;JSON object&amp;quot;&lt;/span&gt;) &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-3&quot;&gt;&lt;a href=&quot;#cb4-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  between (tok (char &lt;span class=&quot;ch&quot;&gt;&amp;#39;{&amp;#39;&lt;/span&gt;)) (tok (char &lt;span class=&quot;ch&quot;&gt;&amp;#39;}&amp;#39;&lt;/span&gt;)) &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-4&quot;&gt;&lt;a href=&quot;#cb4-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    runPermsSep (tok (char &lt;span class=&quot;ch&quot;&gt;&amp;#39;,&amp;#39;&lt;/span&gt;)) fields&lt;/span&gt;
&lt;span id=&quot;cb4-5&quot;&gt;&lt;a href=&quot;#cb4-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-6&quot;&gt;&lt;a href=&quot;#cb4-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;co&quot;&gt;-- common function used by field and optField&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-7&quot;&gt;&lt;a href=&quot;#cb4-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;field&amp;#39; &lt;/span&gt;
&lt;span id=&quot;cb4-8&quot;&gt;&lt;a href=&quot;#cb4-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;  ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;co&quot;&gt;-- key name&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-9&quot;&gt;&lt;a href=&quot;#cb4-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Parser&lt;/span&gt; a &lt;span class=&quot;co&quot;&gt;-- value parser&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-10&quot;&gt;&lt;a href=&quot;#cb4-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Parser&lt;/span&gt; a&lt;/span&gt;
&lt;span id=&quot;cb4-11&quot;&gt;&lt;a href=&quot;#cb4-11&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;field&amp;#39; key value &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; theString key &lt;span class=&quot;op&quot;&gt;*&amp;gt;&lt;/span&gt; tok (char &lt;span class=&quot;ch&quot;&gt;&amp;#39;:&amp;#39;&lt;/span&gt;) &lt;span class=&quot;op&quot;&gt;*&amp;gt;&lt;/span&gt; value&lt;/span&gt;
&lt;span id=&quot;cb4-12&quot;&gt;&lt;a href=&quot;#cb4-12&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-13&quot;&gt;&lt;a href=&quot;#cb4-13&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;field&lt;/span&gt;
&lt;span id=&quot;cb4-14&quot;&gt;&lt;a href=&quot;#cb4-14&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;  ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;co&quot;&gt;-- key name&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-15&quot;&gt;&lt;a href=&quot;#cb4-15&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Parser&lt;/span&gt; a &lt;span class=&quot;co&quot;&gt;-- value parser&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-16&quot;&gt;&lt;a href=&quot;#cb4-16&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Perms&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Parser&lt;/span&gt; a&lt;/span&gt;
&lt;span id=&quot;cb4-17&quot;&gt;&lt;a href=&quot;#cb4-17&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;field key value &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; atom &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; field&amp;#39; key value&lt;/span&gt;
&lt;span id=&quot;cb4-18&quot;&gt;&lt;a href=&quot;#cb4-18&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-19&quot;&gt;&lt;a href=&quot;#cb4-19&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;theField&lt;/span&gt;
&lt;span id=&quot;cb4-20&quot;&gt;&lt;a href=&quot;#cb4-20&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;  ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;co&quot;&gt;-- key name&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-21&quot;&gt;&lt;a href=&quot;#cb4-21&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;co&quot;&gt;-- expected value&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-22&quot;&gt;&lt;a href=&quot;#cb4-22&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Perms&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Parser&lt;/span&gt; ()&lt;/span&gt;
&lt;span id=&quot;cb4-23&quot;&gt;&lt;a href=&quot;#cb4-23&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;theField key value &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; () &lt;span class=&quot;op&quot;&gt;&amp;lt;$&lt;/span&gt; field key (theString value)&lt;/span&gt;
&lt;span id=&quot;cb4-24&quot;&gt;&lt;a href=&quot;#cb4-24&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-25&quot;&gt;&lt;a href=&quot;#cb4-25&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;optField&lt;/span&gt;
&lt;span id=&quot;cb4-26&quot;&gt;&lt;a href=&quot;#cb4-26&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;  ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;co&quot;&gt;-- key name&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-27&quot;&gt;&lt;a href=&quot;#cb4-27&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Parser&lt;/span&gt; a &lt;span class=&quot;co&quot;&gt;-- value parser&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-28&quot;&gt;&lt;a href=&quot;#cb4-28&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Perms&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Parser&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;Maybe&lt;/span&gt; a)&lt;/span&gt;
&lt;span id=&quot;cb4-29&quot;&gt;&lt;a href=&quot;#cb4-29&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;optField key value &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; maybeAtom &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; field&amp;#39; key value&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h4 id=&quot;aside-correct-separator-parsing&quot;&gt;Aside: correct separator
parsing&lt;/h4&gt;
&lt;p&gt;There was only one issue I ran into with
&lt;code&gt;action-permutations&lt;/code&gt;, and it is interesting enough that I
decided to describe it here in more detail.&lt;/p&gt;
&lt;p&gt;Consider, for example, the expression &lt;code
class=&quot;sourceCode haskell&quot;&gt;runPermsSep sep (f &lt;span class=&quot;op&quot;&gt;&amp;lt;$&amp;gt;&lt;/span&gt; atom a &lt;span class=&quot;op&quot;&gt;&amp;lt;*&amp;gt;&lt;/span&gt; atom b &lt;span class=&quot;op&quot;&gt;&amp;lt;*&amp;gt;&lt;/span&gt; atom c)&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;It would expand to&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb5&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb5-1&quot;&gt;&lt;a href=&quot;#cb5-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;(&lt;span class=&quot;fu&quot;&gt;flip&lt;/span&gt; (&lt;span class=&quot;op&quot;&gt;$&lt;/span&gt;) &lt;span class=&quot;op&quot;&gt;&amp;lt;$&amp;gt;&lt;/span&gt; a &lt;span class=&quot;op&quot;&gt;&amp;lt;*&amp;gt;&lt;/span&gt; (&lt;/span&gt;
&lt;span id=&quot;cb5-2&quot;&gt;&lt;a href=&quot;#cb5-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  (sep &lt;span class=&quot;op&quot;&gt;*&amp;gt;&lt;/span&gt; (&lt;span class=&quot;fu&quot;&gt;flip&lt;/span&gt; (&lt;span class=&quot;op&quot;&gt;$&lt;/span&gt;) &lt;span class=&quot;op&quot;&gt;&amp;lt;$&amp;gt;&lt;/span&gt; b &lt;span class=&quot;op&quot;&gt;&amp;lt;*&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-3&quot;&gt;&lt;a href=&quot;#cb5-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  (sep &lt;span class=&quot;op&quot;&gt;*&amp;gt;&lt;/span&gt; (&lt;span class=&quot;fu&quot;&gt;flip&lt;/span&gt; (&lt;span class=&quot;op&quot;&gt;$&lt;/span&gt;) &lt;span class=&quot;op&quot;&gt;&amp;lt;$&amp;gt;&lt;/span&gt; c &lt;span class=&quot;op&quot;&gt;&amp;lt;*&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-4&quot;&gt;&lt;a href=&quot;#cb5-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;fu&quot;&gt;pure&lt;/span&gt; (\xc xb xa &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; f xc xb xa)))))&lt;/span&gt;
&lt;span id=&quot;cb5-5&quot;&gt;&lt;a href=&quot;#cb5-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;op&quot;&gt;&amp;lt;|&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-6&quot;&gt;&lt;a href=&quot;#cb5-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  (sep &lt;span class=&quot;op&quot;&gt;*&amp;gt;&lt;/span&gt; (&lt;span class=&quot;fu&quot;&gt;flip&lt;/span&gt; (&lt;span class=&quot;op&quot;&gt;$&lt;/span&gt;) &lt;span class=&quot;op&quot;&gt;&amp;lt;$&amp;gt;&lt;/span&gt; c &lt;span class=&quot;op&quot;&gt;&amp;lt;*&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-7&quot;&gt;&lt;a href=&quot;#cb5-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  (sep &lt;span class=&quot;op&quot;&gt;*&amp;gt;&lt;/span&gt; (&lt;span class=&quot;fu&quot;&gt;flip&lt;/span&gt; (&lt;span class=&quot;op&quot;&gt;$&lt;/span&gt;) &lt;span class=&quot;op&quot;&gt;&amp;lt;$&amp;gt;&lt;/span&gt; b &lt;span class=&quot;op&quot;&gt;&amp;lt;*&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-8&quot;&gt;&lt;a href=&quot;#cb5-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;fu&quot;&gt;pure&lt;/span&gt; (\xc xb xa &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; f xb xc xa)))))&lt;/span&gt;
&lt;span id=&quot;cb5-9&quot;&gt;&lt;a href=&quot;#cb5-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;))&lt;/span&gt;
&lt;span id=&quot;cb5-10&quot;&gt;&lt;a href=&quot;#cb5-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;op&quot;&gt;&amp;lt;|&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-11&quot;&gt;&lt;a href=&quot;#cb5-11&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;(&lt;span class=&quot;fu&quot;&gt;flip&lt;/span&gt; (&lt;span class=&quot;op&quot;&gt;$&lt;/span&gt;) &lt;span class=&quot;op&quot;&gt;&amp;lt;$&amp;gt;&lt;/span&gt; b &lt;span class=&quot;op&quot;&gt;&amp;lt;*&amp;gt;&lt;/span&gt; (&lt;/span&gt;
&lt;span id=&quot;cb5-12&quot;&gt;&lt;a href=&quot;#cb5-12&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;op&quot;&gt;...&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-13&quot;&gt;&lt;a href=&quot;#cb5-13&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;))&lt;/span&gt;
&lt;span id=&quot;cb5-14&quot;&gt;&lt;a href=&quot;#cb5-14&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;op&quot;&gt;&amp;lt;|&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-15&quot;&gt;&lt;a href=&quot;#cb5-15&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;(&lt;span class=&quot;fu&quot;&gt;flip&lt;/span&gt; (&lt;span class=&quot;op&quot;&gt;$&lt;/span&gt;) &lt;span class=&quot;op&quot;&gt;&amp;lt;$&amp;gt;&lt;/span&gt; c &lt;span class=&quot;op&quot;&gt;&amp;lt;*&amp;gt;&lt;/span&gt; (&lt;/span&gt;
&lt;span id=&quot;cb5-16&quot;&gt;&lt;a href=&quot;#cb5-16&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;op&quot;&gt;...&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-17&quot;&gt;&lt;a href=&quot;#cb5-17&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;))&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;See the problem? Suppose the actual order of the atoms in the input
stream is &lt;code&gt;a&lt;/code&gt;, &lt;code&gt;c&lt;/code&gt;, &lt;code&gt;b&lt;/code&gt;. At the
beginning the parser is lucky to enter the right branch (the one
starting from &lt;code&gt;flip ($) &amp;lt;$&amp;gt; a &amp;lt;*&amp;gt; ...&lt;/code&gt;) on the
first guess. After that, it has two alternatives:
&lt;code&gt;b&lt;/code&gt;-then-&lt;code&gt;c&lt;/code&gt;, or
&lt;code&gt;c&lt;/code&gt;-then-&lt;code&gt;b&lt;/code&gt;. First it enters the
&lt;code&gt;b&lt;/code&gt;-then-&lt;code&gt;c&lt;/code&gt; branch (i.e. the wrong one) and
fails. However, it fails &lt;em&gt;after having consumed some input&lt;/em&gt;
(namely, the separator) — which in libraries like &lt;code&gt;parsec&lt;/code&gt;
and &lt;code&gt;trifecta&lt;/code&gt; means that the other branch (the right one)
won’t be considered.&lt;/p&gt;
&lt;p&gt;We cannot even work around this outside of the library by using
&lt;code&gt;try&lt;/code&gt;, because we can’t insert it in the right place. E.g.
wrapping the separator in &lt;code&gt;try&lt;/code&gt; won’t work. The right place
to insert &lt;code&gt;try&lt;/code&gt; would be around the whole alternative&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb6&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb6-1&quot;&gt;&lt;a href=&quot;#cb6-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  (sep &lt;span class=&quot;op&quot;&gt;*&amp;gt;&lt;/span&gt; (&lt;span class=&quot;fu&quot;&gt;flip&lt;/span&gt; (&lt;span class=&quot;op&quot;&gt;$&lt;/span&gt;) &lt;span class=&quot;op&quot;&gt;&amp;lt;$&amp;gt;&lt;/span&gt; b &lt;span class=&quot;op&quot;&gt;&amp;lt;*&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-2&quot;&gt;&lt;a href=&quot;#cb6-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  (sep &lt;span class=&quot;op&quot;&gt;*&amp;gt;&lt;/span&gt; (&lt;span class=&quot;fu&quot;&gt;flip&lt;/span&gt; (&lt;span class=&quot;op&quot;&gt;$&lt;/span&gt;) &lt;span class=&quot;op&quot;&gt;&amp;lt;$&amp;gt;&lt;/span&gt; c &lt;span class=&quot;op&quot;&gt;&amp;lt;*&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-3&quot;&gt;&lt;a href=&quot;#cb6-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;fu&quot;&gt;pure&lt;/span&gt; (\xc xb xa &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; f xc xb xa)))))&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;but this piece is generated by the lirbary and, as a library user, we
have no control over it.&lt;/p&gt;
&lt;p&gt;The usage of &lt;code&gt;try&lt;/code&gt; inside the library itself is
unsatisfactory, too. Remember, the interface only assumes the
&lt;code&gt;Alternative&lt;/code&gt; instance, which has no notion of
&lt;code&gt;try&lt;/code&gt;. If we had to make it less generic by imposing a
&lt;code&gt;Parsing&lt;/code&gt; constraint, that would be really unfortunate.&lt;/p&gt;
&lt;p&gt;Fortunately, once identified, this problem is not hard to fix
properly — and no usage of &lt;code&gt;try&lt;/code&gt; is required! All we need is
to change &lt;code&gt;runPermsSep&lt;/code&gt; so that it expands to the tree where
separator parsing is factored out:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb7&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb7-1&quot;&gt;&lt;a href=&quot;#cb7-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;(&lt;span class=&quot;fu&quot;&gt;flip&lt;/span&gt; (&lt;span class=&quot;op&quot;&gt;$&lt;/span&gt;) &lt;span class=&quot;op&quot;&gt;&amp;lt;$&amp;gt;&lt;/span&gt; a &lt;span class=&quot;op&quot;&gt;&amp;lt;*&amp;gt;&lt;/span&gt; sep &lt;span class=&quot;op&quot;&gt;*&amp;gt;&lt;/span&gt; (&lt;/span&gt;
&lt;span id=&quot;cb7-2&quot;&gt;&lt;a href=&quot;#cb7-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  (&lt;span class=&quot;fu&quot;&gt;flip&lt;/span&gt; (&lt;span class=&quot;op&quot;&gt;$&lt;/span&gt;) &lt;span class=&quot;op&quot;&gt;&amp;lt;$&amp;gt;&lt;/span&gt; b &lt;span class=&quot;op&quot;&gt;&amp;lt;*&amp;gt;&lt;/span&gt; sep &lt;span class=&quot;op&quot;&gt;*&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb7-3&quot;&gt;&lt;a href=&quot;#cb7-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  (&lt;span class=&quot;fu&quot;&gt;flip&lt;/span&gt; (&lt;span class=&quot;op&quot;&gt;$&lt;/span&gt;) &lt;span class=&quot;op&quot;&gt;&amp;lt;$&amp;gt;&lt;/span&gt; c &lt;span class=&quot;op&quot;&gt;&amp;lt;*&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb7-4&quot;&gt;&lt;a href=&quot;#cb7-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;fu&quot;&gt;pure&lt;/span&gt; (\xc xb xa &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; f xc xb xa)))))&lt;/span&gt;
&lt;span id=&quot;cb7-5&quot;&gt;&lt;a href=&quot;#cb7-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;op&quot;&gt;&amp;lt;|&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb7-6&quot;&gt;&lt;a href=&quot;#cb7-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  (&lt;span class=&quot;fu&quot;&gt;flip&lt;/span&gt; (&lt;span class=&quot;op&quot;&gt;$&lt;/span&gt;) &lt;span class=&quot;op&quot;&gt;&amp;lt;$&amp;gt;&lt;/span&gt; c &lt;span class=&quot;op&quot;&gt;&amp;lt;*&amp;gt;&lt;/span&gt; sep &lt;span class=&quot;op&quot;&gt;*&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb7-7&quot;&gt;&lt;a href=&quot;#cb7-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  (&lt;span class=&quot;fu&quot;&gt;flip&lt;/span&gt; (&lt;span class=&quot;op&quot;&gt;$&lt;/span&gt;) &lt;span class=&quot;op&quot;&gt;&amp;lt;$&amp;gt;&lt;/span&gt; b &lt;span class=&quot;op&quot;&gt;&amp;lt;*&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb7-8&quot;&gt;&lt;a href=&quot;#cb7-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;fu&quot;&gt;pure&lt;/span&gt; (\xc xb xa &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; f xb xc xa)))&lt;/span&gt;
&lt;span id=&quot;cb7-9&quot;&gt;&lt;a href=&quot;#cb7-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;))&lt;/span&gt;
&lt;span id=&quot;cb7-10&quot;&gt;&lt;a href=&quot;#cb7-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;op&quot;&gt;&amp;lt;|&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb7-11&quot;&gt;&lt;a href=&quot;#cb7-11&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;(&lt;span class=&quot;fu&quot;&gt;flip&lt;/span&gt; (&lt;span class=&quot;op&quot;&gt;$&lt;/span&gt;) &lt;span class=&quot;op&quot;&gt;&amp;lt;$&amp;gt;&lt;/span&gt; b &lt;span class=&quot;op&quot;&gt;&amp;lt;*&amp;gt;&lt;/span&gt; sep &lt;span class=&quot;op&quot;&gt;*&amp;gt;&lt;/span&gt; (&lt;/span&gt;
&lt;span id=&quot;cb7-12&quot;&gt;&lt;a href=&quot;#cb7-12&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;op&quot;&gt;...&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb7-13&quot;&gt;&lt;a href=&quot;#cb7-13&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;))&lt;/span&gt;
&lt;span id=&quot;cb7-14&quot;&gt;&lt;a href=&quot;#cb7-14&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;op&quot;&gt;&amp;lt;|&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb7-15&quot;&gt;&lt;a href=&quot;#cb7-15&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;(&lt;span class=&quot;fu&quot;&gt;flip&lt;/span&gt; (&lt;span class=&quot;op&quot;&gt;$&lt;/span&gt;) &lt;span class=&quot;op&quot;&gt;&amp;lt;$&amp;gt;&lt;/span&gt; c &lt;span class=&quot;op&quot;&gt;&amp;lt;*&amp;gt;&lt;/span&gt; sep &lt;span class=&quot;op&quot;&gt;*&amp;gt;&lt;/span&gt; (&lt;/span&gt;
&lt;span id=&quot;cb7-16&quot;&gt;&lt;a href=&quot;#cb7-16&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;op&quot;&gt;...&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb7-17&quot;&gt;&lt;a href=&quot;#cb7-17&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;))&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now, all alternatives start with atoms, so we have full control over
whether they consume any input.&lt;/p&gt;
&lt;p&gt;Mathematically, this demonstrates that &lt;code&gt;&amp;lt;*&amp;gt;&lt;/code&gt; does
not distribute over &lt;code&gt;&amp;lt;|&amp;gt;&lt;/code&gt; for some backtracking
parsers. Note that such distributive property is not required by the
&lt;code&gt;Alternative&lt;/code&gt; class.&lt;/p&gt;
&lt;p&gt;Even for parser monads that allow backtracking by default
(&lt;code&gt;attoparsec&lt;/code&gt;, &lt;code&gt;polyparse&lt;/code&gt;) and for which there’s
no semantic difference between the two versions, this change improves
efficiency by sharing separator parsing across branches.&lt;/p&gt;
&lt;p&gt;My patch fixing the issue has been incorporated into the version
&lt;code&gt;0.0.0.1&lt;/code&gt; of &lt;code&gt;action-permutations&lt;/code&gt;.&lt;/p&gt;
&lt;h3 id=&quot;arrays&quot;&gt;Arrays&lt;/h3&gt;
&lt;p&gt;Arrays should be easier to parse than objects in that the order of
the elements is fixed. Still, we need to handle separators (commas)
between array elements.&lt;/p&gt;
&lt;p&gt;If we interpreted arrays as lists, then the schema combinator for
arrays might look like&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb8&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb8-1&quot;&gt;&lt;a href=&quot;#cb8-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;array&lt;/span&gt;
&lt;span id=&quot;cb8-2&quot;&gt;&lt;a href=&quot;#cb8-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;  ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Parser&lt;/span&gt; a &lt;span class=&quot;co&quot;&gt;-- parser for a signle element&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb8-3&quot;&gt;&lt;a href=&quot;#cb8-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Parser&lt;/span&gt; [a] &lt;span class=&quot;co&quot;&gt;-- parser for the array&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Implementation would be straightforward, too.&lt;/p&gt;
&lt;p&gt;However, in our JSON schema we use arrays as tuples rather than
lists. That is, we typically expect an array of a fixed number of
heterogeneous elements. Thus we’d like to combine these tuple elements
into a single parser using the applicative interface.&lt;/p&gt;
&lt;p&gt;Let’s say we expect a 2-tuple of a string (a person’s name) and an
object (that person’s address).&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb9&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb9-1&quot;&gt;&lt;a href=&quot;#cb9-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Address&lt;/span&gt; &lt;span class=&quot;co&quot;&gt;-- = ...&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb9-2&quot;&gt;&lt;a href=&quot;#cb9-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Person&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb9-3&quot;&gt;&lt;a href=&quot;#cb9-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;dt&quot;&gt;Person&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb9-4&quot;&gt;&lt;a href=&quot;#cb9-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;dt&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;co&quot;&gt;-- name&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb9-5&quot;&gt;&lt;a href=&quot;#cb9-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;dt&quot;&gt;Address&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Written by hand, the parser may look like&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb10&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb10-1&quot;&gt;&lt;a href=&quot;#cb10-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;address ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Parser&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Address&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb10-2&quot;&gt;&lt;a href=&quot;#cb10-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;address &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; _&lt;/span&gt;
&lt;span id=&quot;cb10-3&quot;&gt;&lt;a href=&quot;#cb10-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb10-4&quot;&gt;&lt;a href=&quot;#cb10-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;personAddress &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;/span&gt;
&lt;span id=&quot;cb10-5&quot;&gt;&lt;a href=&quot;#cb10-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  between (tok (char &lt;span class=&quot;ch&quot;&gt;&amp;#39;[&amp;#39;&lt;/span&gt;)) (tok (char &lt;span class=&quot;ch&quot;&gt;&amp;#39;]&amp;#39;&lt;/span&gt;)) &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb10-6&quot;&gt;&lt;a href=&quot;#cb10-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;dt&quot;&gt;Person&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;&amp;lt;$&amp;gt;&lt;/span&gt; string &lt;span class=&quot;op&quot;&gt;&amp;lt;*&lt;/span&gt; sep &lt;span class=&quot;op&quot;&gt;&amp;lt;*&amp;gt;&lt;/span&gt; address&lt;/span&gt;
&lt;span id=&quot;cb10-7&quot;&gt;&lt;a href=&quot;#cb10-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;where&lt;/span&gt; sep &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; tok &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; char &lt;span class=&quot;ch&quot;&gt;&amp;#39;,&amp;#39;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;It makes sense to move brackets parsing to the &lt;code&gt;array&lt;/code&gt;
combinator:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb11&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb11-1&quot;&gt;&lt;a href=&quot;#cb11-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;array ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Parser&lt;/span&gt; a &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Parser&lt;/span&gt; a&lt;/span&gt;
&lt;span id=&quot;cb11-2&quot;&gt;&lt;a href=&quot;#cb11-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;array p &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; (&lt;span class=&quot;op&quot;&gt;&amp;lt;?&amp;gt;&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;quot;JSON array&amp;quot;&lt;/span&gt;) &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb11-3&quot;&gt;&lt;a href=&quot;#cb11-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  between (tok (char &lt;span class=&quot;ch&quot;&gt;&amp;#39;[&amp;#39;&lt;/span&gt;)) (tok (char &lt;span class=&quot;ch&quot;&gt;&amp;#39;]&amp;#39;&lt;/span&gt;)) p&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;But what should we do with the commas? Manually interspersing
elements with separators is error-prone and doesn’t correspond to my
view of a high-level JSON schema description.&lt;/p&gt;
&lt;p&gt;Inserting comma parsers automatically isn’t impossible — after all,
it is done in the &lt;code&gt;action-permutations&lt;/code&gt; package and we used
it to parse object fields, which are comma-separated, too. But it cannot
be as easy as adding a separator to every element since there’s one less
separators than elements. We have somehow to detect the last element and
not to expect a separator after it.&lt;/p&gt;
&lt;p&gt;A nice and simple way to achieve this is with a &lt;a
href=&quot;/articles/2013-03-31-flavours-of-free-applicative-functors&quot;&gt;free
applicative functor&lt;/a&gt;. A free applicative functor will allow us to
capture the whole applicative expression and postpone the decision on
where to insert separator parsers until we can tell which element is the
last one. In this case we’ll use Twan van Laarhoven’s free applicative,
as implemented in the &lt;code&gt;free&lt;/code&gt; package.&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb12&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb12-1&quot;&gt;&lt;a href=&quot;#cb12-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;element ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Parser&lt;/span&gt; a &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Ap&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Parser&lt;/span&gt; a&lt;/span&gt;
&lt;span id=&quot;cb12-2&quot;&gt;&lt;a href=&quot;#cb12-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;element &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; liftAp&lt;/span&gt;
&lt;span id=&quot;cb12-3&quot;&gt;&lt;a href=&quot;#cb12-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb12-4&quot;&gt;&lt;a href=&quot;#cb12-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;theArray ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Ap&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Parser&lt;/span&gt; a &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Parser&lt;/span&gt; a&lt;/span&gt;
&lt;span id=&quot;cb12-5&quot;&gt;&lt;a href=&quot;#cb12-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;theArray p &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; between (tok (char &lt;span class=&quot;ch&quot;&gt;&amp;#39;[&amp;#39;&lt;/span&gt;)) (tok (char &lt;span class=&quot;ch&quot;&gt;&amp;#39;]&amp;#39;&lt;/span&gt;)) &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; go p&lt;/span&gt;
&lt;span id=&quot;cb12-6&quot;&gt;&lt;a href=&quot;#cb12-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb12-7&quot;&gt;&lt;a href=&quot;#cb12-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;    go ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Ap&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Parser&lt;/span&gt; a &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Parser&lt;/span&gt; a&lt;/span&gt;
&lt;span id=&quot;cb12-8&quot;&gt;&lt;a href=&quot;#cb12-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    go (&lt;span class=&quot;dt&quot;&gt;Ap&lt;/span&gt; p (&lt;span class=&quot;dt&quot;&gt;Pure&lt;/span&gt; f)) &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; f &lt;span class=&quot;op&quot;&gt;&amp;lt;$&amp;gt;&lt;/span&gt; p&lt;/span&gt;
&lt;span id=&quot;cb12-9&quot;&gt;&lt;a href=&quot;#cb12-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    go (&lt;span class=&quot;dt&quot;&gt;Ap&lt;/span&gt; p1 pn) &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;flip&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;id&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;&amp;lt;$&amp;gt;&lt;/span&gt; p1 &lt;span class=&quot;op&quot;&gt;&amp;lt;*&lt;/span&gt; tok (char &lt;span class=&quot;ch&quot;&gt;&amp;#39;,&amp;#39;&lt;/span&gt;) &lt;span class=&quot;op&quot;&gt;&amp;lt;*&amp;gt;&lt;/span&gt; go pn&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Like object fields, array elements have a special type which makes it
clear which pieces exactly are comma-separated.&lt;/p&gt;
&lt;p&gt;In fact, the applicative functor &lt;code&gt;Perms&lt;/code&gt; is essentially
the free applicative functor &lt;code&gt;Ap&lt;/code&gt; plus branching.&lt;/p&gt;
&lt;h4 id=&quot;optional-array-elements&quot;&gt;Optional array elements&lt;/h4&gt;
&lt;p&gt;Now comes the twist. Some of the array elements may be optional — in
the same way as positional function arguments in some languages may be
optional. Since the elements are positional, if one of them is omitted,
all subsequent ones have to be omitted, too — otherwise we won’t be able
to tell which one was omitted, exactly.&lt;/p&gt;
&lt;p&gt;For that reason, all optional elements should come after all the
non-optional ones; if not, then we’ve made a mistake while designing (or
describing) our schema. Ideally, our solution should catch such
mistakes, too.&lt;/p&gt;
&lt;p&gt;So, how can the above solution be adapted to handle optional
arguments?&lt;/p&gt;
&lt;h5 id=&quot;attempt-1&quot;&gt;Attempt #1:&lt;/h5&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb13&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb13-1&quot;&gt;&lt;a href=&quot;#cb13-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;optElement ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Parser&lt;/span&gt; a &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Ap&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Parser&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;Maybe&lt;/span&gt; a)&lt;/span&gt;
&lt;span id=&quot;cb13-2&quot;&gt;&lt;a href=&quot;#cb13-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;optElement p &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; element &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; optional p&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Here &lt;code&gt;optional&lt;/code&gt; is a combinator defined in
&lt;code&gt;Control.Applicative&lt;/code&gt; as&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb14&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb14-1&quot;&gt;&lt;a href=&quot;#cb14-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;optional v &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Just&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;&amp;lt;$&amp;gt;&lt;/span&gt; v &lt;span class=&quot;op&quot;&gt;&amp;lt;|&amp;gt;&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;pure&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Nothing&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This won’t work at all, as it doesn’t give us any information about
whether it’s an optional element or just a parser that happens to return
a &lt;code&gt;Maybe&lt;/code&gt; type.&lt;/p&gt;
&lt;h5 id=&quot;attempt-2&quot;&gt;Attempt #2:&lt;/h5&gt;
&lt;p&gt;Well, let’s just add a flag indicating whether the element was
created using &lt;code&gt;optElement&lt;/code&gt;, shall we?&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb15&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb15-1&quot;&gt;&lt;a href=&quot;#cb15-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;El&lt;/span&gt; a &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb15-2&quot;&gt;&lt;a href=&quot;#cb15-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;dt&quot;&gt;El&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb15-3&quot;&gt;&lt;a href=&quot;#cb15-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;dt&quot;&gt;Bool&lt;/span&gt; &lt;span class=&quot;co&quot;&gt;-- is optional?&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb15-4&quot;&gt;&lt;a href=&quot;#cb15-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    (&lt;span class=&quot;dt&quot;&gt;Parser&lt;/span&gt; a)&lt;/span&gt;
&lt;span id=&quot;cb15-5&quot;&gt;&lt;a href=&quot;#cb15-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb15-6&quot;&gt;&lt;a href=&quot;#cb15-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;element ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Parser&lt;/span&gt; a &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Ap&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;El&lt;/span&gt; a&lt;/span&gt;
&lt;span id=&quot;cb15-7&quot;&gt;&lt;a href=&quot;#cb15-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;element &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; liftAp &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;El&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;False&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb15-8&quot;&gt;&lt;a href=&quot;#cb15-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb15-9&quot;&gt;&lt;a href=&quot;#cb15-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;optElement ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Parser&lt;/span&gt; a &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Ap&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;El&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;Maybe&lt;/span&gt; a)&lt;/span&gt;
&lt;span id=&quot;cb15-10&quot;&gt;&lt;a href=&quot;#cb15-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;optElement &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; liftAp &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;El&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;True&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt; optional&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now we can check that optional arguments come after non-optional
ones. If an element’s parse result is &lt;code&gt;Nothing&lt;/code&gt;, we also know
whether that element is an optional one, and whether we should stop
trying to parse the subsequent elements.&lt;/p&gt;
&lt;p&gt;Still, there are two related issues preventing this version from
working:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;How do we actually know when a parser returns
&lt;code&gt;Nothing&lt;/code&gt;? Once we lift a parser into the free applicative,
its return type becomes existentially quantified, i.e. we should treat
it as polymorphic and cannot assume it has form &lt;code&gt;Maybe a&lt;/code&gt; (by
pattern-matching on it), even if we can convince ourselves by looking at
the &lt;code&gt;Bool&lt;/code&gt; flag that it indeed must be of that form.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Similarly, once we’ve detected an absent optional element
(assuming for a second that it is possible), we have to force all the
remaining optional parsers to return &lt;code&gt;Nothing&lt;/code&gt; without
parsing anything. But again, we cannot convince the compiler that
&lt;code&gt;Nothing&lt;/code&gt; is an acceptable return value of those
parsers.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h5 id=&quot;attempt-3&quot;&gt;Attempt #3:&lt;/h5&gt;
&lt;p&gt;So, we need certain run-time values (the optionality flag) to
introduce type-level information (namely, that the parser’s return type
has form &lt;code&gt;Maybe a&lt;/code&gt;). That’s exactly what GADTs do!&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb16&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb16-1&quot;&gt;&lt;a href=&quot;#cb16-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;El&lt;/span&gt; a &lt;span class=&quot;kw&quot;&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb16-2&quot;&gt;&lt;a href=&quot;#cb16-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;dt&quot;&gt;El&lt;/span&gt;&lt;span class=&quot;ot&quot;&gt; ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Parser&lt;/span&gt; a &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;El&lt;/span&gt; a&lt;/span&gt;
&lt;span id=&quot;cb16-3&quot;&gt;&lt;a href=&quot;#cb16-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;dt&quot;&gt;OptEl&lt;/span&gt;&lt;span class=&quot;ot&quot;&gt; ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Parser&lt;/span&gt; a &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;El&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;Maybe&lt;/span&gt; a)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;El&lt;/code&gt;’s two constructors are a more powerful version of our
old &lt;code&gt;Bool&lt;/code&gt; flag. They let us see whether the element is
optional, and if so, guarantee that its parser’s return type is
&lt;code&gt;Maybe&lt;/code&gt;ish.&lt;/p&gt;
&lt;p&gt;And here’s the code for the parsing functions:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb17&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb17-1&quot;&gt;&lt;a href=&quot;#cb17-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;element ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Parser&lt;/span&gt; a &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Ap&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;El&lt;/span&gt; a&lt;/span&gt;
&lt;span id=&quot;cb17-2&quot;&gt;&lt;a href=&quot;#cb17-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;element &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; liftAp &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;El&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb17-3&quot;&gt;&lt;a href=&quot;#cb17-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb17-4&quot;&gt;&lt;a href=&quot;#cb17-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;optElement ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Parser&lt;/span&gt; a &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Ap&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;El&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;Maybe&lt;/span&gt; a)&lt;/span&gt;
&lt;span id=&quot;cb17-5&quot;&gt;&lt;a href=&quot;#cb17-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;optElement &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; liftAp &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;OptEl&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb17-6&quot;&gt;&lt;a href=&quot;#cb17-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb17-7&quot;&gt;&lt;a href=&quot;#cb17-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;theArray ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Ap&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;El&lt;/span&gt; a &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Parser&lt;/span&gt; a&lt;/span&gt;
&lt;span id=&quot;cb17-8&quot;&gt;&lt;a href=&quot;#cb17-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;theArray p &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; between (tok (char &lt;span class=&quot;ch&quot;&gt;&amp;#39;[&amp;#39;&lt;/span&gt;)) (tok (char &lt;span class=&quot;ch&quot;&gt;&amp;#39;]&amp;#39;&lt;/span&gt;)) &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb17-9&quot;&gt;&lt;a href=&quot;#cb17-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  go &lt;span class=&quot;dt&quot;&gt;True&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;False&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;False&lt;/span&gt; p&lt;/span&gt;
&lt;span id=&quot;cb17-10&quot;&gt;&lt;a href=&quot;#cb17-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb17-11&quot;&gt;&lt;a href=&quot;#cb17-11&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;    go ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Bool&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Bool&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Bool&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Ap&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;El&lt;/span&gt; a &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Parser&lt;/span&gt; a&lt;/span&gt;
&lt;span id=&quot;cb17-12&quot;&gt;&lt;a href=&quot;#cb17-12&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    go _ _ _ (&lt;span class=&quot;dt&quot;&gt;Pure&lt;/span&gt; x) &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;pure&lt;/span&gt; x&lt;/span&gt;
&lt;span id=&quot;cb17-13&quot;&gt;&lt;a href=&quot;#cb17-13&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    go isFirst optionalOccurred optionalOmitted (&lt;span class=&quot;dt&quot;&gt;Ap&lt;/span&gt; el1 eln) &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb17-14&quot;&gt;&lt;a href=&quot;#cb17-14&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;kw&quot;&gt;let&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb17-15&quot;&gt;&lt;a href=&quot;#cb17-15&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;        eltSequenceError ::&lt;/span&gt; a&lt;/span&gt;
&lt;span id=&quot;cb17-16&quot;&gt;&lt;a href=&quot;#cb17-16&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;        eltSequenceError &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb17-17&quot;&gt;&lt;a href=&quot;#cb17-17&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;          &lt;span class=&quot;fu&quot;&gt;error&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;quot;theArray: a non-optional element after an optional one&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb17-18&quot;&gt;&lt;a href=&quot;#cb17-18&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb17-19&quot;&gt;&lt;a href=&quot;#cb17-19&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;        &lt;span class=&quot;op&quot;&gt;!&lt;/span&gt;_check &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb17-20&quot;&gt;&lt;a href=&quot;#cb17-20&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;          &lt;span class=&quot;kw&quot;&gt;case&lt;/span&gt; el1 &lt;span class=&quot;kw&quot;&gt;of&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb17-21&quot;&gt;&lt;a href=&quot;#cb17-21&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;            &lt;span class=&quot;dt&quot;&gt;El&lt;/span&gt; {} &lt;span class=&quot;op&quot;&gt;|&lt;/span&gt; optionalOccurred &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; eltSequenceError&lt;/span&gt;
&lt;span id=&quot;cb17-22&quot;&gt;&lt;a href=&quot;#cb17-22&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;            _ &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; ()&lt;/span&gt;
&lt;span id=&quot;cb17-23&quot;&gt;&lt;a href=&quot;#cb17-23&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;kw&quot;&gt;in&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb17-24&quot;&gt;&lt;a href=&quot;#cb17-24&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;        &lt;span class=&quot;kw&quot;&gt;if&lt;/span&gt; optionalOmitted&lt;/span&gt;
&lt;span id=&quot;cb17-25&quot;&gt;&lt;a href=&quot;#cb17-25&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;          &lt;span class=&quot;kw&quot;&gt;then&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb17-26&quot;&gt;&lt;a href=&quot;#cb17-26&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;            &lt;span class=&quot;kw&quot;&gt;case&lt;/span&gt; el1 &lt;span class=&quot;kw&quot;&gt;of&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb17-27&quot;&gt;&lt;a href=&quot;#cb17-27&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;              &lt;span class=&quot;dt&quot;&gt;El&lt;/span&gt; {} &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; eltSequenceError&lt;/span&gt;
&lt;span id=&quot;cb17-28&quot;&gt;&lt;a href=&quot;#cb17-28&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;              &lt;span class=&quot;dt&quot;&gt;OptEl&lt;/span&gt; {} &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; go &lt;span class=&quot;dt&quot;&gt;False&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;True&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;True&lt;/span&gt; eln &lt;span class=&quot;op&quot;&gt;&amp;lt;*&amp;gt;&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;pure&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Nothing&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb17-29&quot;&gt;&lt;a href=&quot;#cb17-29&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;          &lt;span class=&quot;kw&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb17-30&quot;&gt;&lt;a href=&quot;#cb17-30&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;            &lt;span class=&quot;kw&quot;&gt;let&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb17-31&quot;&gt;&lt;a href=&quot;#cb17-31&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;              sep &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;if&lt;/span&gt; isFirst &lt;span class=&quot;kw&quot;&gt;then&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;pure&lt;/span&gt; () &lt;span class=&quot;kw&quot;&gt;else&lt;/span&gt; () &lt;span class=&quot;op&quot;&gt;&amp;lt;$&lt;/span&gt; tok (char &lt;span class=&quot;ch&quot;&gt;&amp;#39;,&amp;#39;&lt;/span&gt;)&lt;/span&gt;
&lt;span id=&quot;cb17-32&quot;&gt;&lt;a href=&quot;#cb17-32&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;            &lt;span class=&quot;kw&quot;&gt;case&lt;/span&gt; el1 &lt;span class=&quot;kw&quot;&gt;of&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb17-33&quot;&gt;&lt;a href=&quot;#cb17-33&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;              &lt;span class=&quot;dt&quot;&gt;El&lt;/span&gt; p1 &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb17-34&quot;&gt;&lt;a href=&quot;#cb17-34&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;                &lt;span class=&quot;fu&quot;&gt;flip&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;id&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;&amp;lt;$&lt;/span&gt; sep &lt;span class=&quot;op&quot;&gt;&amp;lt;*&amp;gt;&lt;/span&gt; p1 &lt;span class=&quot;op&quot;&gt;&amp;lt;*&amp;gt;&lt;/span&gt; go &lt;span class=&quot;dt&quot;&gt;False&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;False&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;False&lt;/span&gt; eln&lt;/span&gt;
&lt;span id=&quot;cb17-35&quot;&gt;&lt;a href=&quot;#cb17-35&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;              &lt;span class=&quot;dt&quot;&gt;OptEl&lt;/span&gt; p1 &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb17-36&quot;&gt;&lt;a href=&quot;#cb17-36&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;                r1 &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; optional &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; sep &lt;span class=&quot;op&quot;&gt;*&amp;gt;&lt;/span&gt; p1&lt;/span&gt;
&lt;span id=&quot;cb17-37&quot;&gt;&lt;a href=&quot;#cb17-37&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;                go &lt;span class=&quot;dt&quot;&gt;False&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;True&lt;/span&gt; (isNothing r1) eln &lt;span class=&quot;op&quot;&gt;&amp;lt;*&amp;gt;&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;pure&lt;/span&gt; r1&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;theArray&lt;/code&gt; is a state machine with three pieces of state:
&lt;code&gt;isFirst&lt;/code&gt;, &lt;code&gt;optionalOccurred&lt;/code&gt; and
&lt;code&gt;optionalOmitted&lt;/code&gt;. &lt;code&gt;isFirst&lt;/code&gt; and
&lt;code&gt;optionalOmitted&lt;/code&gt; are used to guide actual parsing, while
&lt;code&gt;optionalOccurred&lt;/code&gt; is needed to check the proper arrangement
of optional vs. non-optional arguments.&lt;/p&gt;
&lt;h2 id=&quot;conclusions&quot;&gt;Conclusions&lt;/h2&gt;
&lt;p&gt;Although the standard approach to JSON parsing is to parse into a
generic JSON representation first, the article shows that an alternative
approach — parsing the expected structure directly — is also viable and
can be employed to improve error reporting.&lt;/p&gt;
&lt;p&gt;Of course, the tricks and ideas described here are not specific to
JSON. Understanding how they work and how to use them may become handy
in a variety of parsing situations.&lt;/p&gt;
</description>
                        <pubDate>Sun, 20 Apr 2014 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2014-04-20-json-validation-combinators</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2014-04-20-json-validation-combinators.html</guid>
                </item>
        
                <item>
                        <title>Find out the type of an expression/function with typed holes</title>
                        <description>&lt;p&gt;An often asked Haskell question is how to find out a type of a
locally defined function or expression.&lt;/p&gt;
&lt;p&gt;The classic solutions are to &lt;a
href=&quot;http://stackoverflow.com/a/2128742/110081&quot;&gt;specify the wrong type
and read the error message&lt;/a&gt;, or get help from a tool like &lt;a
href=&quot;https://github.com/bitc/hdevtools&quot;&gt;hdevtools&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Here’s a new one: use the &lt;a
href=&quot;http://www.haskell.org/haskellwiki/GHC/TypedHoles&quot;&gt;typed holes&lt;/a&gt;
feature of GHC 7.8+.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;On the surface, typed holes solve a somewhat different problem: find
out the desired type of the yet unwritten code, while we want to find
out the actual type of the written code.&lt;/p&gt;
&lt;p&gt;But typed holes are very easy to adapt for our needs. The
&lt;code&gt;asTypeOf :: a -&amp;gt; a -&amp;gt; a&lt;/code&gt; function forces the types of
its two arguments to unify. So we can force the type of a hole to be the
same as the type of an existing expression — and voilà!&lt;/p&gt;
&lt;p&gt;(Note that &lt;code&gt;asTypeOf&lt;/code&gt; is exported from
&lt;code&gt;Prelude&lt;/code&gt;, so typically you don’t have to import anything to
bring it in scope. Nor do you have to enable any extensions for typed
holes to work.)&lt;/p&gt;
&lt;p&gt;In my case I had code like this&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb1&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb1-1&quot;&gt;&lt;a href=&quot;#cb1-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;op&quot;&gt;...&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-2&quot;&gt;&lt;a href=&quot;#cb1-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;let&lt;/span&gt; leave &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; branch testName &lt;span class=&quot;dt&quot;&gt;False&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-3&quot;&gt;&lt;a href=&quot;#cb1-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;op&quot;&gt;...&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;and I wanted to see what the type of &lt;code&gt;leave&lt;/code&gt; is. So I
appended &lt;code&gt;`asTypeOf` _&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb2&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb2-1&quot;&gt;&lt;a href=&quot;#cb2-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;op&quot;&gt;...&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-2&quot;&gt;&lt;a href=&quot;#cb2-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;let&lt;/span&gt; leave &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; branch testName &lt;span class=&quot;dt&quot;&gt;False&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;`asTypeOf`&lt;/span&gt; _&lt;/span&gt;
&lt;span id=&quot;cb2-3&quot;&gt;&lt;a href=&quot;#cb2-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;op&quot;&gt;...&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;and &lt;code&gt;ghci&lt;/code&gt; told me:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;*Test.Tasty.Runners.Html&amp;gt; :r
[2 of 2] Compiling Test.Tasty.Runners.Html ( Test/Tasty/Runners/Html.hs, interpreted )

Test/Tasty/Runners/Html.hs:86:58:
    Found hole ‘_’
      with type: Maybe (String, H.AttributeValue)
                 -&amp;gt; H.AttributeValue
                 -&amp;gt; H.AttributeValue
                 -&amp;gt; H.AttributeValue
                 -&amp;gt; H.Markup
    Relevant bindings include
      leave :: Maybe (String, H.AttributeValue)
               -&amp;gt; H.AttributeValue
               -&amp;gt; H.AttributeValue
               -&amp;gt; H.AttributeValue
               -&amp;gt; H.Markup
        (bound at Test/Tasty/Runners/Html.hs:86:17)
      mkSummary :: H.Html -&amp;gt; Summary
        (bound at Test/Tasty/Runners/Html.hs:88:17)
      status :: Tasty.Status (bound at Test/Tasty/Runners/Html.hs:82:13)
      i :: IntMap.Key (bound at Test/Tasty/Runners/Html.hs:79:11)
      testName :: String (bound at Test/Tasty/Runners/Html.hs:78:19)
      runTest :: t
                 -&amp;gt; String
                 -&amp;gt; t1
                 -&amp;gt; Traversal (Functor.Compose (t2 IO) (Const Summary))
        (bound at Test/Tasty/Runners/Html.hs:78:9)
      runner :: Tasty.OptionSet
                -&amp;gt; Tasty.TestTree
                -&amp;gt; m (IntMap.IntMap (STM.TVar Tasty.Status) -&amp;gt; IO Bool)
        (bound at Test/Tasty/Runners/Html.hs:72:3)
      (Some bindings suppressed; use -fmax-relevant-binds=N or -fno-max-relevant-binds)
    In the second argument of ‘asTypeOf’, namely ‘_’
    In the expression: branch testName False `asTypeOf` _
    In an equation for ‘leave’:
        leave = branch testName False `asTypeOf` _
Failed, modules loaded: Paths_tasty_html.
*Paths_tasty_html&amp;gt; &lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As you see, I got not just the type of the hole itself, but also the
types of some other relevant definitions — very handy!&lt;/p&gt;
&lt;p&gt;Another thing you can do is put &lt;code&gt;_ = _&lt;/code&gt; inside a
&lt;code&gt;let&lt;/code&gt; or &lt;code&gt;where&lt;/code&gt; bindings group and play with
&lt;code&gt;-fmax-relevant-binds=N&lt;/code&gt; and
&lt;code&gt;-fno-max-relevant-binds&lt;/code&gt;.&lt;/p&gt;
</description>
                        <pubDate>Thu, 13 Mar 2014 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2014-03-13-type-of-local-function</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2014-03-13-type-of-local-function.html</guid>
                </item>
        
                <item>
                        <title>Happy, Alex, and GHC 7.8</title>
                        <description>&lt;p&gt;As we approach the 7.8 release of GHC, more and more people are
running into problems with packages that use Alex and/or Happy for
parsing.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;The errors look like&lt;/p&gt;
&lt;div style=&quot;font-size:10px;&quot;&gt;
&lt;pre&gt;&lt;code&gt;templates/GenericTemplate.hs:104:22:
    Couldn&amp;#39;t match expected type ‛Bool’
                with actual type ‛Happy_GHC_Exts.Int#’
    In the expression:
      (n Happy_GHC_Exts.&amp;lt;# (0# :: Happy_GHC_Exts.Int#))
    In a stmt of a pattern guard for
                   a case alternative:
      (n Happy_GHC_Exts.&amp;lt;# (0# :: Happy_GHC_Exts.Int#))
    In a case alternative:
        n | (n Happy_GHC_Exts.&amp;lt;# (0# :: Happy_GHC_Exts.Int#))
          -&amp;gt; (happyReduceArr Happy_Data_Array.! rule) i tk st
          where
              rule
                = (Happy_GHC_Exts.I#
                     ((Happy_GHC_Exts.negateInt#
                         ((n Happy_GHC_Exts.+# (1# :: Happy_GHC_Exts.Int#))))))&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;for Happy and&lt;/p&gt;
&lt;div style=&quot;font-size:10px;&quot;&gt;
&lt;pre&gt;&lt;code&gt;    Pattern bindings containing unlifted types should use an outermost bang pattern:
      ((I# (ord_c))) = ord c
    In the expression:
      let
        (base) = alexIndexInt32OffAddr alex_base s
        ((I# (ord_c))) = ord c
        (offset) = (base +# ord_c)
        ....
      in
        case new_s of {
          -1# -&amp;gt; (new_acc, input)
          _ -&amp;gt; alex_scan_tkn
                 user orig_input (len +# 1#) new_input new_s new_acc }
    In a case alternative:
        Just (c, new_input)
          -&amp;gt; let
               (base) = alexIndexInt32OffAddr alex_base s
               ((I# (ord_c))) = ord c
               ....
             in
               case new_s of {
                 -1# -&amp;gt; (new_acc, input)
                 _ -&amp;gt; alex_scan_tkn
                        user orig_input (len +# 1#) new_input new_s new_acc }
    In the second argument of ‘seq’, namely
      ‘case alexGetChar input of {
         Nothing -&amp;gt; (new_acc, input)
         Just (c, new_input)
           -&amp;gt; let
                (base) = ...
                ....
              in
                case new_s of {
                  -1# -&amp;gt; ...
                  _ -&amp;gt; alex_scan_tkn
                         user orig_input (len +# 1#) new_input new_s new_acc } }’&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;for Alex. (These are not all the error messages that are produced by
GHC, but hopefully enough that this article is googlable.)&lt;/p&gt;
&lt;p&gt;First I give instructions on how to fix these problems, and then
explain why they arise in the first place.&lt;/p&gt;
&lt;h2 id=&quot;tldr-how-do-i-fix-the-package&quot;&gt;TL;DR: how do I fix the
package?&lt;/h2&gt;
&lt;h3 id=&quot;as-a-maintainer&quot;&gt;As a maintainer&lt;/h3&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;&lt;p&gt;Install the &lt;em&gt;latest&lt;/em&gt; versions of &lt;code&gt;alex&lt;/code&gt; and
&lt;code&gt;happy&lt;/code&gt;. GHC 7.8 support was added in &lt;code&gt;alex-3.1.0&lt;/code&gt;
and &lt;code&gt;happy-1.19.0&lt;/code&gt;, but later versions contain additional
bugfixes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Double-check that &lt;code&gt;cabal&lt;/code&gt; picks the latest versions of
these tools: in your package’s source tree run&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb3&quot;&gt;&lt;pre
class=&quot;sourceCode bash&quot;&gt;&lt;code class=&quot;sourceCode bash&quot;&gt;&lt;span id=&quot;cb3-1&quot;&gt;&lt;a href=&quot;#cb3-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ex&quot;&gt;cabal&lt;/span&gt; configure &lt;span class=&quot;at&quot;&gt;-v&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;grep&lt;/span&gt; &lt;span class=&quot;at&quot;&gt;-e&lt;/span&gt; alex &lt;span class=&quot;at&quot;&gt;-e&lt;/span&gt; happy&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The output should look like&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Using alex version 3.1.3 found on system at: /home/feuerbach/bin/alex
Using happy version 1.19.3 found on system at: /home/feuerbach/bin/happy&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Bump the package’s version (the fourth component is enough:
e.g. &lt;code&gt;1.2.3&lt;/code&gt; -&amp;gt; &lt;code&gt;1.2.3.1&lt;/code&gt;), build the package
and upload:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb5&quot;&gt;&lt;pre
class=&quot;sourceCode bash&quot;&gt;&lt;code class=&quot;sourceCode bash&quot;&gt;&lt;span id=&quot;cb5-1&quot;&gt;&lt;a href=&quot;#cb5-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ex&quot;&gt;cabal&lt;/span&gt; build&lt;/span&gt;
&lt;span id=&quot;cb5-2&quot;&gt;&lt;a href=&quot;#cb5-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ex&quot;&gt;cabal&lt;/span&gt; sdist&lt;/span&gt;
&lt;span id=&quot;cb5-3&quot;&gt;&lt;a href=&quot;#cb5-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ex&quot;&gt;cabal&lt;/span&gt; upload dist/&lt;span class=&quot;va&quot;&gt;$pkg&lt;/span&gt;-&lt;span class=&quot;va&quot;&gt;$version&lt;/span&gt;.tar.gz&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;That’s it; no actual source code modification to your package is
necessary. If you’re curious as to why this works, read on.&lt;/p&gt;
&lt;h3 id=&quot;as-a-user&quot;&gt;As a user&lt;/h3&gt;
&lt;p&gt;First of all, check that you have latest alex and happy installed.
That by itself can resolve your problem.&lt;/p&gt;
&lt;p&gt;If it doesn’t, notify the package maintainer(s) about this problem
and send them a link to this article. Only they are in a position to fix
the problem properly.&lt;/p&gt;
&lt;p&gt;Until the maintainer(s) react, you can fix the problem locally as
follows:&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;&lt;p&gt;Get into the source tree:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb6&quot;&gt;&lt;pre
class=&quot;sourceCode bash&quot;&gt;&lt;code class=&quot;sourceCode bash&quot;&gt;&lt;span id=&quot;cb6-1&quot;&gt;&lt;a href=&quot;#cb6-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ex&quot;&gt;cabal&lt;/span&gt; get &lt;span class=&quot;va&quot;&gt;$pkg&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-2&quot;&gt;&lt;a href=&quot;#cb6-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;bu&quot;&gt;cd&lt;/span&gt; &lt;span class=&quot;va&quot;&gt;$pkg&lt;/span&gt;-&lt;span class=&quot;va&quot;&gt;$version&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;(If &lt;code&gt;cabal&lt;/code&gt; says it doesn’t know about the
&lt;code&gt;get&lt;/code&gt; command, you have to update it with&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb7&quot;&gt;&lt;pre
class=&quot;sourceCode bash&quot;&gt;&lt;code class=&quot;sourceCode bash&quot;&gt;&lt;span id=&quot;cb7-1&quot;&gt;&lt;a href=&quot;#cb7-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ex&quot;&gt;cabal&lt;/span&gt; install cabal-install&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The command was called &lt;code&gt;unpack&lt;/code&gt; before, but since you are
using GHC 7.8 now, the older versions of &lt;code&gt;cabal&lt;/code&gt; will get you
in trouble anyway.)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Now that you’re in the source tree, run&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb8&quot;&gt;&lt;pre
class=&quot;sourceCode bash&quot;&gt;&lt;code class=&quot;sourceCode bash&quot;&gt;&lt;span id=&quot;cb8-1&quot;&gt;&lt;a href=&quot;#cb8-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ex&quot;&gt;cabal&lt;/span&gt; clean&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;You may think «but I’ve just downloaded a fresh copy of the package’s
source — surely it is clean!» Not really; read on for the
details.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Finally,&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb9&quot;&gt;&lt;pre
class=&quot;sourceCode bash&quot;&gt;&lt;code class=&quot;sourceCode bash&quot;&gt;&lt;span id=&quot;cb9-1&quot;&gt;&lt;a href=&quot;#cb9-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ex&quot;&gt;cabal&lt;/span&gt; install&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;should run without any &lt;code&gt;alex&lt;/code&gt;- or
&lt;code&gt;happy&lt;/code&gt;-related errors.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;whats-going-on-here&quot;&gt;What’s going on here?&lt;/h2&gt;
&lt;h3 id=&quot;code-produced-by-old-happy-and-alex-no-longer-builds&quot;&gt;Code
produced by old Happy and Alex no longer builds&lt;/h3&gt;
&lt;p&gt;Because Alex and Happy strive to produce the most efficient code,
they make use of unboxed types and primitives. And those are affected by
certain changes in GHC 7.8:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://ghc.haskell.org/trac/ghc/wiki/PrimBool&quot;&gt;PrimOps for
comparing unboxed values now return &lt;code&gt;Int#&lt;/code&gt; instead of
&lt;code&gt;Bool&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a
href=&quot;https://ghc.haskell.org/trac/ghc/changeset/7f23a5dfd8ea061a25f13b1ecef799d834732668/ghc&quot;&gt;Lazy
unlifted bindings are an error now&lt;/a&gt;. For background on this one, see
&lt;a href=&quot;https://ghc.haskell.org/trac/ghc/ticket/2806&quot;&gt;#2806&lt;/a&gt;, &lt;a
href=&quot;https://ghc.haskell.org/trac/ghc/ticket/3278&quot;&gt;#3278&lt;/a&gt; and &lt;a
href=&quot;https://ghc.haskell.org/trac/ghc/ticket/8022&quot;&gt;#8022&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Happy and Alex were then updated to generate code that builds with
the new GHC. So, it seems, just updating
&lt;code&gt;happy&lt;/code&gt;/&lt;code&gt;alex&lt;/code&gt; should do the trick. Not so
fast!&lt;/p&gt;
&lt;h3 id=&quot;cabal-includes-generated-code-in-the-source-distribution&quot;&gt;cabal
includes generated code in the source distribution&lt;/h3&gt;
&lt;p&gt;When &lt;code&gt;cabal&lt;/code&gt; creates a source distribution for uploading
to hackage (&lt;code&gt;cabal sdist&lt;/code&gt;), it includes the files generated
by &lt;code&gt;alex&lt;/code&gt; and &lt;code&gt;happy&lt;/code&gt; in the tarball. So even when
you have the new &lt;code&gt;alex&lt;/code&gt; and &lt;code&gt;happy&lt;/code&gt; installed,
&lt;code&gt;cabal install&lt;/code&gt; will not see the need to regenerate
&lt;code&gt;.hs&lt;/code&gt; files from &lt;code&gt;.x&lt;/code&gt; and &lt;code&gt;.y&lt;/code&gt; sources,
and will run into the errors described above.&lt;/p&gt;
&lt;p&gt;That’s why maintainers have to re-upload their tarballs generated
with new &lt;code&gt;alex&lt;/code&gt; and &lt;code&gt;happy&lt;/code&gt;; and until they do,
users have to run &lt;code&gt;cabal get&lt;/code&gt; and
&lt;code&gt;cabal clean&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The rationale behind this &lt;code&gt;cabal&lt;/code&gt; behavior is not to force
users install &lt;code&gt;alex&lt;/code&gt; or &lt;code&gt;happy&lt;/code&gt;. Alas, it doesn’t
work so well in practice:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Dec 09 19:37:21 dcoutts refold: there&amp;#39;s a few problems with our shipped pre-processed sources system
Dec 09 19:37:41 dcoutts it doesn&amp;#39;t interact well with using  build-tools: happy
Dec 09 19:38:03 dcoutts if there are shipped sources then obviously we do not need happy
Dec 09 19:38:14 dcoutts the shipped sources currently go in dist
Dec 09 19:38:18 dcoutts that then fails if you clean
Dec 09 19:38:33 dcoutts it only allows one instance of shipped sources
Dec 09 19:38:52 dcoutts e.g. for happy &amp;amp; alex, they can produce ghc-specific output or generic output
Dec 09 19:39:20 dcoutts this is less of a problem these days since in practice there are
                        not other compilers
Dec 09 19:40:19 dcoutts and then this new problem, if we do ship sources, we don&amp;#39;t know what version
                        of the pre-processor generated them, so we cannot easily hack around version
                        incompatibilities
Dec 09 19:40:21 refold  yes, using dist is hack
Dec 09 19:40:30 dcoutts the plan was to use a different dir
Dec 09 19:40:31 refold  also fails with a different --builddir
Dec 09 19:40:34 dcoutts right&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;See also &lt;a
href=&quot;https://github.com/haskell/cabal/issues/130&quot;&gt;#130&lt;/a&gt; and &lt;a
href=&quot;https://github.com/haskell/cabal/issues/1685&quot;&gt;#1685&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&quot;cabal-sdist-is-not-pure&quot;&gt;cabal sdist is not “pure”&lt;/h3&gt;
&lt;p&gt;We usually think of &lt;code&gt;cabal sdist&lt;/code&gt; as a pure function
taking in the source tree and producing the tarball. It’s not that
simple.&lt;/p&gt;
&lt;p&gt;Above I wrote that &lt;code&gt;cabal sdist&lt;/code&gt; includes
&lt;code&gt;alex&lt;/code&gt; and &lt;code&gt;happy&lt;/code&gt;-generated sources in the
tarball. However, as Mikhail Glushenkov &lt;a
href=&quot;https://github.com/haskell/cabal/issues/130#issuecomment-61067995&quot;&gt;explains&lt;/a&gt;,
it doesn’t actually &lt;em&gt;generate&lt;/em&gt; them. It only includes them if
they are already present as an artifact of a previous
&lt;code&gt;cabal build&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;When I uploaded &lt;a
href=&quot;http://hackage.haskell.org/package/haskell-src-exts-1.16.0&quot;&gt;haskell-src-exts-1.16.0&lt;/a&gt;,
I wasn’t aware of this and apparently ran &lt;code&gt;cabal clean&lt;/code&gt;
before &lt;code&gt;cabal sdist&lt;/code&gt;. As a consequence, the tarball doesn’t
have the &lt;code&gt;dist/&lt;/code&gt; subdirectory with generated files as you can
easily check.&lt;/p&gt;
&lt;p&gt;In order to install that particular version of
&lt;code&gt;haskell-src-exts&lt;/code&gt;, a user needs to have &lt;code&gt;happy&lt;/code&gt;
installed (and if her &lt;code&gt;happy&lt;/code&gt; is old, she’ll get the exact
same error described above). When I learned about it, I made a point
release, 1.16.0.1, which does include the &lt;code&gt;happy&lt;/code&gt; output.&lt;/p&gt;
&lt;p&gt;So this is another thing that maintainers need to be aware of and
watch out for.&lt;/p&gt;
</description>
                        <pubDate>Sat, 08 Mar 2014 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2014-03-08-happy-alex-ghc-7.8</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2014-03-08-happy-alex-ghc-7.8.html</guid>
                </item>
        
                <item>
                        <title>cabal sandbox tips</title>
                        <description>&lt;p&gt;In case you &lt;a href=&quot;/ccc/22&quot;&gt;missed it&lt;/a&gt;, starting from version
1.18 &lt;code&gt;cabal-install&lt;/code&gt; has awesome sandboxing capabilities.
Here I share a couple of tricks that will make your sandboxing
experience even better.&lt;/p&gt;
&lt;!--more--&gt;
&lt;h2 id=&quot;location-independent-sandboxes&quot;&gt;Location-independent
sandboxes&lt;/h2&gt;
&lt;p&gt;By default, &lt;code&gt;cabal&lt;/code&gt; uses sandbox only in the directory
where &lt;code&gt;cabal.sandbox.config&lt;/code&gt; is present. This is inconvenient
when sharing a sandbox among multiple projects, and in general makes it
somewhat fragile.&lt;/p&gt;
&lt;p&gt;With &lt;code&gt;cabal 1.19&lt;/code&gt; (i.e. &lt;code&gt;cabal HEAD&lt;/code&gt; as of now)
you can set the &lt;code&gt;CABAL_SANDBOX_CONFIG&lt;/code&gt; environment variable
to the path to your &lt;code&gt;cabal.sandbox.config&lt;/code&gt;, and the
corresponding sandbox will be used regardless of your current
directory.&lt;/p&gt;
&lt;p&gt;I’ve defined convenience functions for myself such as&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb1&quot;&gt;&lt;pre
class=&quot;sourceCode bash&quot;&gt;&lt;code class=&quot;sourceCode bash&quot;&gt;&lt;span id=&quot;cb1-1&quot;&gt;&lt;a href=&quot;#cb1-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;fu&quot;&gt;tasty()&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-2&quot;&gt;&lt;a href=&quot;#cb1-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;bu&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;va&quot;&gt;CABAL_SANDBOX_CONFIG&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;va&quot;&gt;$HOME&lt;/span&gt;/prog/tasty/sandbox/cabal.sandbox.config&lt;/span&gt;
&lt;span id=&quot;cb1-3&quot;&gt;&lt;a href=&quot;#cb1-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;va&quot;&gt;sandbox_name&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;=&lt;/span&gt;tasty&lt;/span&gt;
&lt;span id=&quot;cb1-4&quot;&gt;&lt;a href=&quot;#cb1-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;for every sandbox I commonly use.&lt;/p&gt;
&lt;p&gt;Notice how I also set the &lt;code&gt;sandbox_name&lt;/code&gt; variable to the
human-readable name of the sandbox. It can be displayed in the prompt as
follows:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb2&quot;&gt;&lt;pre
class=&quot;sourceCode bash&quot;&gt;&lt;code class=&quot;sourceCode bash&quot;&gt;&lt;span id=&quot;cb2-1&quot;&gt;&lt;a href=&quot;#cb2-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ex&quot;&gt;setopt&lt;/span&gt; prompt_subst &lt;span class=&quot;co&quot;&gt;# force prompt re-evaluation&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-2&quot;&gt;&lt;a href=&quot;#cb2-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;va&quot;&gt;PROMPT&lt;/span&gt;&lt;span class=&quot;op&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;st&quot;&gt;&amp;#39;${sandbox_name+[sandbox: $sandbox_name] }%~ %% &amp;#39;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;(sandbox name in the prompt idea is due to &lt;a
href=&quot;http://www.reddit.com/user/cameleon&quot;&gt;/u/cameleon&lt;/a&gt;)&lt;/p&gt;
&lt;h2 id=&quot;sandbox-aware-ghc&quot;&gt;Sandbox-aware ghc&lt;/h2&gt;
&lt;p&gt;Sandboxes only affect &lt;code&gt;cabal&lt;/code&gt;, but not &lt;code&gt;ghc&lt;/code&gt; or
&lt;code&gt;ghci&lt;/code&gt; when those are invoked directly. &lt;a
href=&quot;https://github.com/haskell/cabal/issues/1627&quot;&gt;At some point in the
future&lt;/a&gt; we’ll be able to write&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% cabal exec ghc ...&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For now I’ve defined the following sandbox-aware wrappers for
&lt;code&gt;ghc&lt;/code&gt; and &lt;code&gt;ghci&lt;/code&gt;:&lt;/p&gt;
&lt;script src=&quot;https://gist.github.com/UnkindPartition/9365969.js&quot;&gt;&lt;/script&gt;
&lt;p&gt;Clone the repo somewhere&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% git clone https://gist.github.com/9365969.git ghc_sandbox&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;and include in your &lt;code&gt;.bashrc&lt;/code&gt; or &lt;code&gt;.zshrc&lt;/code&gt;&lt;/p&gt;
&lt;pre class=&quot;hash&quot;&gt;&lt;code&gt;. ~/path/to/ghc_sandbox/ghc_sandbox.sh&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;(Why am I wrapping &lt;code&gt;ghci&lt;/code&gt; instead of using
&lt;code&gt;cabal repl&lt;/code&gt;? &lt;code&gt;cabal repl&lt;/code&gt; has some side-effects,
like re-installing packages, that are not always desirable. And
&lt;code&gt;ghci&lt;/code&gt; is much faster to start, too.)&lt;/p&gt;
</description>
                        <pubDate>Wed, 05 Mar 2014 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2014-03-05-cabal-sandbox-tips</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2014-03-05-cabal-sandbox-tips.html</guid>
                </item>
        
                <item>
                        <title>tasty-0.8 and other news</title>
                        <description>&lt;p&gt;I’m glad to announce the &lt;a
href=&quot;http://hackage.haskell.org/package/tasty-0.8&quot;&gt;0.8 release&lt;/a&gt; of
&lt;strong&gt;tasty&lt;/strong&gt;, a modern Haskell testing framework.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;Among the important user-visible changes are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;New running modes &lt;code&gt;--hide-successes&lt;/code&gt; and
&lt;code&gt;--quiet&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Short flags for some existing options (&lt;code&gt;-p&lt;/code&gt; for
&lt;code&gt;--pattern&lt;/code&gt;, &lt;code&gt;-j&lt;/code&gt; for
&lt;code&gt;--num-threads&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Timeout support&lt;/li&gt;
&lt;li&gt;Possibility to pass options via environment variables&lt;/li&gt;
&lt;li&gt;Fix of a resources-related bug&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For details, see the &lt;a
href=&quot;https://github.com/UnkindPartition/tasty/blob/master/CHANGES.md&quot;&gt;CHANGELOG&lt;/a&gt;
and &lt;a href=&quot;http://documentup.com/feuerbach/tasty&quot;&gt;README&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;social&quot;&gt;Social&lt;/h2&gt;
&lt;p&gt;tasty now has a &lt;a
href=&quot;https://groups.google.com/forum/#!forum/haskell-tasty&quot;&gt;mailing
list&lt;/a&gt; and an IRC channel #tasty at FreeNode. The IRC channel is &lt;a
href=&quot;http://ircbrowse.net/tasty&quot;&gt;logged at ircbrowse.net&lt;/a&gt; (thanks to
Chris Done).&lt;/p&gt;
&lt;h2 id=&quot;volunteers&quot;&gt;Volunteers&lt;/h2&gt;
&lt;p&gt;I’d like to thank people who kindly responded to my requests for help
with tasty-related packages:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/jdnavarro&quot;&gt;Danny Navarro&lt;/a&gt; and &lt;a
href=&quot;https://github.com/ccatalfo&quot;&gt;Chris Catalfo&lt;/a&gt; are working on &lt;a
href=&quot;https://github.com/UnkindPartition/tasty-html&quot;&gt;tasty-html&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/iduhetonas&quot;&gt;Tyler Huffman&lt;/a&gt; is going
to improve the &lt;a
href=&quot;https://github.com/mitchellwrosen/tasty-hspec&quot;&gt;HSpec test
provider&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;dependencies&quot;&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;I recently started to pay more attention to (transitive) dependencies
of my packages. More transitive dependencies (esp. those that I do not
control) means greater probability that something will break, not to
mention the compile times.&lt;/p&gt;
&lt;p&gt;As Vincent Hanquez put it,&lt;/p&gt;
&lt;blockquote class=&quot;twitter-tweet&quot; lang=&quot;en&quot;&gt;
&lt;p&gt;
operation-dependency-streamline. roll your own copies of code and types
instead of depending on different packages.
&lt;/p&gt;
— Vincent Hanquez (&lt;span class=&quot;citation&quot;
data-cites=&quot;vincenthz&quot;&gt;@vincenthz&lt;/span&gt;)
&lt;a href=&quot;https://twitter.com/vincenthz/statuses/439008732773888001&quot;&gt;February
27, 2014&lt;/a&gt;
&lt;/blockquote&gt;
&lt;script async src=&quot;//platform.twitter.com/widgets.js&quot; charset=&quot;utf-8&quot;&gt;&lt;/script&gt;
&lt;p&gt;For comparison, here are dependency graphs for tasty-0.7 and
tasty-0.8, produced by John Millikin’s new &lt;a
href=&quot;http://hackage.haskell.org/package/cabal-graphdeps&quot;&gt;cabal-graphdeps&lt;/a&gt;
tool:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/img/deps-tasty-0.7.png&quot; width=&quot;600&quot; title=&quot;tasty-0.7&quot;&gt;
&lt;img src=&quot;/img/deps-tasty-0.8.png&quot; width=&quot;600&quot; title=&quot;tasty-0.8&quot;&gt;&lt;/p&gt;
&lt;p&gt;The gains were achieved by:&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;Dropping the dependency on &lt;code&gt;either&lt;/code&gt;. First I just copied
the code over to tasty, but then realized that using exceptions in that
case was an even better solution.&lt;/li&gt;
&lt;li&gt;Refusing to depend on &lt;code&gt;reducers&lt;/code&gt;. Instead, I just copied
the desired pieces.&lt;/li&gt;
&lt;li&gt;Using &lt;code&gt;unbounded-delays&lt;/code&gt; for timeouts instead of
&lt;code&gt;data-timeout&lt;/code&gt; that I considered initially. This one actually
shows the danger of fat dependencies — one of
&lt;code&gt;data-timeout&lt;/code&gt;’s dependencies &lt;a
href=&quot;https://github.com/mvv/data-textual/issues/1&quot;&gt;fails to build with
GHC 7.4&lt;/a&gt; due to an alleged &lt;a
href=&quot;https://github.com/ekmett/tagged/pull/16&quot;&gt;compiler bug&lt;/a&gt;
affecting some piece of code that is completely irrelevant for my
purposes.&lt;/li&gt;
&lt;/ol&gt;
</description>
                        <pubDate>Mon, 03 Mar 2014 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2014-03-03-tasty-0.8</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2014-03-03-tasty-0.8.html</guid>
                </item>
        
                <item>
                        <title>My Haskell will</title>
                        <description>&lt;p&gt;I &lt;a
href=&quot;http://www.haskell.org/pipermail/haskell-cafe/2014-January/112466.html&quot;&gt;hate
it&lt;/a&gt; when maintainers become unreachable. At the same time, I’m not
immune to that myself (if nothing else, I could be hit by a bus
tomorrow).&lt;/p&gt;
&lt;p&gt;So I contacted a few people with a request to become backup
maintainers (BM) for some of my more popular Haskell packages, and they
kindly agreed.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;Specifically:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://ocharles.org.uk/&quot;&gt;Oliver Charles&lt;/a&gt; is now BM for
all my testing-related packages: tasty and its add-ons, smallcheck,
obsolete test-framework add-ons, and ansi-terminal (a dependency of
tasty)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/bergmark&quot;&gt;Adam Bergmark&lt;/a&gt; is now BM
for the haskell-suite projects: haskell-names, haskell-packages,
hse-cpp, and traverse-with-class (a dependency of haskell-names)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://w3future.com/&quot;&gt;Sjoerd Visscher&lt;/a&gt; is co-BM for
traverse-with-class&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://oleksandrmanzyuk.wordpress.com/&quot;&gt;Oleksandr
Manzyuk&lt;/a&gt; is now BM for ariadne and bert (a dependency of
ariadne)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Being a backup maintainer comes with very light responsibilities:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;should I become unreachable (temporarily or permanently), and a
change has to be made to a package to keep it usable, the BM is supposed
to review, apply, and release that change.&lt;/li&gt;
&lt;li&gt;if I am unreachable for a long time or permanently, and there’s a
person/people who want to take over maintenance/development of all or
some of the packages, and the BM has no objections to them doing so, the
BM is supposed to give them the necessary privileges. (Of course, that
person may be the BM him/herself!)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The BM for a package is added as a maintainer of that package on
hackage and as a collaborator for the package’s github repository.&lt;/p&gt;
&lt;p&gt;To make it clear, there’s no obligation for the BM to fix bugs or
continue the development after I disappear. It would be unreasonable to
request a person to commit to such a responsibility at an indefinite
point in the future.&lt;/p&gt;
&lt;p&gt;I assume that if a project is important, there will be people willing
to take care of it; and if it isn’t, then it doesn’t matter anyway. The
main responsibility of the BM is thus to make it easy for such a
hypothetical person to take over.&lt;/p&gt;
&lt;p&gt;As to what it means to be «unreachable», I completely trust my BM’s
judgement here. I don’t want them to follow any bureaucratic procedures.
The risk of something going wrong is very low and easily outweighed by
the benefits of timely response to problems.&lt;/p&gt;
&lt;p&gt;One package that doesn’t have a BM yet is standalone-haddock. If you
use it and would like to become a BM, please get in touch.&lt;/p&gt;
&lt;p&gt;I also encourage other package maintainers to follow this example and
appoint BMs for their popular packages.&lt;/p&gt;
</description>
                        <pubDate>Sat, 08 Feb 2014 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2014-02-08-my-haskell-will</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2014-02-08-my-haskell-will.html</guid>
                </item>
        
                <item>
                        <title>Resources in Tasty (update)</title>
                        <description>&lt;p&gt;In a &lt;a href=&quot;2013-12-10-tasty-resources&quot;&gt;recent article&lt;/a&gt; I
described how resources were introduced to the &lt;a
href=&quot;http://documentup.com/feuerbach/tasty&quot;&gt;Tasty&lt;/a&gt; test framework,
as well as some alternative approaches. This article describes the new
API, introduced in Tasty 0.7.&lt;/p&gt;
&lt;p&gt;To recap, there was a function, &lt;code&gt;withResource&lt;/code&gt;, that
handled creation/acquisition and disposal of resources, but if you
needed to access the resource directly in the tests, you had to store
the resource in an &lt;code&gt;IORef&lt;/code&gt; (or similar) as part of the
initialization routine.&lt;/p&gt;
&lt;p&gt;At the time it seemed acceptable, but later I discovered that when
the number of resources was bigger than one or two, or even not known in
advance (when tests are generated rather than just written down), this
was inconvenient enough to start looking for a different solution.&lt;/p&gt;
&lt;p&gt;One of the major problems with tests receiving the resource value
directly, as in&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb1&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb1-1&quot;&gt;&lt;a href=&quot;#cb1-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;withResource&lt;/span&gt;
&lt;span id=&quot;cb1-2&quot;&gt;&lt;a href=&quot;#cb1-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;  ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;IO&lt;/span&gt; a&lt;/span&gt;
&lt;span id=&quot;cb1-3&quot;&gt;&lt;a href=&quot;#cb1-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; (a &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;IO&lt;/span&gt; ())&lt;/span&gt;
&lt;span id=&quot;cb1-4&quot;&gt;&lt;a href=&quot;#cb1-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; (a &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;TestTree&lt;/span&gt;)&lt;/span&gt;
&lt;span id=&quot;cb1-5&quot;&gt;&lt;a href=&quot;#cb1-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;TestTree&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;… was that the resource could be used not only in the tests
themselves, but to &lt;em&gt;construct&lt;/em&gt; the tests, which is bad/wrong for
a number of reasons. For instance, we don’t want to create the resources
when we’re not running tests, but we still want to know which tests we
have.&lt;/p&gt;
&lt;p&gt;The solution I found is to pass not the &lt;em&gt;value&lt;/em&gt; of the
resource, but an &lt;em&gt;IO action&lt;/em&gt; yielding the resource.&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb2&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb2-1&quot;&gt;&lt;a href=&quot;#cb2-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;withResource&lt;/span&gt;
&lt;span id=&quot;cb2-2&quot;&gt;&lt;a href=&quot;#cb2-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;  ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;IO&lt;/span&gt; a&lt;/span&gt;
&lt;span id=&quot;cb2-3&quot;&gt;&lt;a href=&quot;#cb2-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; (a &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;IO&lt;/span&gt; ())&lt;/span&gt;
&lt;span id=&quot;cb2-4&quot;&gt;&lt;a href=&quot;#cb2-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;IO&lt;/span&gt; a &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;TestTree&lt;/span&gt;)&lt;/span&gt;
&lt;span id=&quot;cb2-5&quot;&gt;&lt;a href=&quot;#cb2-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;TestTree&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Even though it’s an IO action, it doesn’t &lt;em&gt;acquire&lt;/em&gt; the
resource, because such a resource wouldn’t be shared across multiple
tests, which is the semantics we’re after. Instead, it returns the
resource which has been acquired (think: reads from an
&lt;code&gt;IORef&lt;/code&gt; or &lt;code&gt;MVar&lt;/code&gt;). But thanks to it being an
&lt;code&gt;IO&lt;/code&gt; action, it can only be used inside a test, and not to
construct or alter tests based on the resource value.&lt;/p&gt;
&lt;p&gt;Here’s a modified example from the last article which works with this
new API:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb3&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb3-1&quot;&gt;&lt;a href=&quot;#cb3-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Test.Tasty&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-2&quot;&gt;&lt;a href=&quot;#cb3-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Test.Tasty.HUnit&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-3&quot;&gt;&lt;a href=&quot;#cb3-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-4&quot;&gt;&lt;a href=&quot;#cb3-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;co&quot;&gt;-- assumed defintions&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-5&quot;&gt;&lt;a href=&quot;#cb3-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Foo&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-6&quot;&gt;&lt;a href=&quot;#cb3-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;acquire ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;IO&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Foo&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-7&quot;&gt;&lt;a href=&quot;#cb3-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;release ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Foo&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;IO&lt;/span&gt; ()&lt;/span&gt;
&lt;span id=&quot;cb3-8&quot;&gt;&lt;a href=&quot;#cb3-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;testWithFoo ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Foo&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Assertion&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-9&quot;&gt;&lt;a href=&quot;#cb3-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;(acquire, release, testWithFoo) &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;undefined&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-10&quot;&gt;&lt;a href=&quot;#cb3-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-11&quot;&gt;&lt;a href=&quot;#cb3-11&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;main &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-12&quot;&gt;&lt;a href=&quot;#cb3-12&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  defaultMain &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-13&quot;&gt;&lt;a href=&quot;#cb3-13&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    withResource acquire release tests&lt;/span&gt;
&lt;span id=&quot;cb3-14&quot;&gt;&lt;a href=&quot;#cb3-14&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-15&quot;&gt;&lt;a href=&quot;#cb3-15&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;tests ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;IO&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Foo&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;TestTree&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-16&quot;&gt;&lt;a href=&quot;#cb3-16&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;tests getResource &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-17&quot;&gt;&lt;a href=&quot;#cb3-17&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  testGroup &lt;span class=&quot;st&quot;&gt;&amp;quot;Tests&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-18&quot;&gt;&lt;a href=&quot;#cb3-18&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    [ testCase &lt;span class=&quot;st&quot;&gt;&amp;quot;x&amp;quot;&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; getResource &lt;span class=&quot;op&quot;&gt;&amp;gt;&amp;gt;=&lt;/span&gt; testWithFoo&lt;/span&gt;
&lt;span id=&quot;cb3-19&quot;&gt;&lt;a href=&quot;#cb3-19&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    ]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
</description>
                        <pubDate>Sun, 29 Dec 2013 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2013-12-29-tasty-resources-2</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2013-12-29-tasty-resources-2.html</guid>
                </item>
        
                <item>
                        <title>Custom options in Tasty</title>
                        <description>&lt;p&gt;&lt;a href=&quot;http://hackage.haskell.org/package/tasty-0.6&quot;&gt;Tasty 0.6&lt;/a&gt;
is released, making it possible to create custom options just for your
test suite!&lt;/p&gt;
&lt;p&gt;Add your own option in three easy steps:&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;Define a datatype to represent the option, and make it an instance
of &lt;code&gt;IsOption&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Register the options with the &lt;code&gt;includingOptions&lt;/code&gt;
ingredient&lt;/li&gt;
&lt;li&gt;To query the option value, use &lt;code&gt;askOption&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Examples follow.&lt;/p&gt;
&lt;h2 id=&quot;ignoring-a-test&quot;&gt;Ignoring a test&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;My use case is a test suite that has a number of tests that fail on a
certain build bot. I can’t fix the build bot configuration ATM, so I’d
like to be able to mark these tests as known-fail in the build script
for this particular build bot. — &lt;a
href=&quot;https://github.com/UnkindPartition/tasty/issues/36&quot;&gt;23Skidoo&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;To some extent this is just a way around Tasty’s limited pattern
language (which will improve, too!), but I still find it pretty
nice.&lt;/p&gt;
&lt;p&gt;With the following code, you can disable the second test by passing a
&lt;code&gt;--buildbot&lt;/code&gt; command-line option.&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb1&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb1-1&quot;&gt;&lt;a href=&quot;#cb1-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;{-# LANGUAGE DeriveDataTypeable #-}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-2&quot;&gt;&lt;a href=&quot;#cb1-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-3&quot;&gt;&lt;a href=&quot;#cb1-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Test.Tasty&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-4&quot;&gt;&lt;a href=&quot;#cb1-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Test.Tasty.Options&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-5&quot;&gt;&lt;a href=&quot;#cb1-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Test.Tasty.HUnit&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-6&quot;&gt;&lt;a href=&quot;#cb1-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Data.Typeable&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;Typeable&lt;/span&gt;)&lt;/span&gt;
&lt;span id=&quot;cb1-7&quot;&gt;&lt;a href=&quot;#cb1-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Data.Tagged&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-8&quot;&gt;&lt;a href=&quot;#cb1-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Data.Proxy&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-9&quot;&gt;&lt;a href=&quot;#cb1-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Options.Applicative&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-10&quot;&gt;&lt;a href=&quot;#cb1-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-11&quot;&gt;&lt;a href=&quot;#cb1-11&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;newtype&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;BuildBot&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;BuildBot&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Bool&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-12&quot;&gt;&lt;a href=&quot;#cb1-12&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;deriving&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;Eq&lt;/span&gt;, &lt;span class=&quot;dt&quot;&gt;Ord&lt;/span&gt;, &lt;span class=&quot;dt&quot;&gt;Typeable&lt;/span&gt;)&lt;/span&gt;
&lt;span id=&quot;cb1-13&quot;&gt;&lt;a href=&quot;#cb1-13&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-14&quot;&gt;&lt;a href=&quot;#cb1-14&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;instance&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;IsOption&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;BuildBot&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-15&quot;&gt;&lt;a href=&quot;#cb1-15&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  defaultValue &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;BuildBot&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;False&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-16&quot;&gt;&lt;a href=&quot;#cb1-16&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  parseValue &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;fmap&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;BuildBot&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt; safeRead&lt;/span&gt;
&lt;span id=&quot;cb1-17&quot;&gt;&lt;a href=&quot;#cb1-17&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  optionName &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;quot;buildbot&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-18&quot;&gt;&lt;a href=&quot;#cb1-18&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  optionHelp &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;quot;Running under a build bot&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-19&quot;&gt;&lt;a href=&quot;#cb1-19&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  optionCLParser &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-20&quot;&gt;&lt;a href=&quot;#cb1-20&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;fu&quot;&gt;fmap&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;BuildBot&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-21&quot;&gt;&lt;a href=&quot;#cb1-21&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    switch&lt;/span&gt;
&lt;span id=&quot;cb1-22&quot;&gt;&lt;a href=&quot;#cb1-22&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      (  long (untag (&lt;span class=&quot;ot&quot;&gt;optionName ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Tagged&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;BuildBot&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;String&lt;/span&gt;))&lt;/span&gt;
&lt;span id=&quot;cb1-23&quot;&gt;&lt;a href=&quot;#cb1-23&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;op&quot;&gt;&amp;lt;&amp;gt;&lt;/span&gt; help (untag (&lt;span class=&quot;ot&quot;&gt;optionHelp ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Tagged&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;BuildBot&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;String&lt;/span&gt;))&lt;/span&gt;
&lt;span id=&quot;cb1-24&quot;&gt;&lt;a href=&quot;#cb1-24&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      )&lt;/span&gt;
&lt;span id=&quot;cb1-25&quot;&gt;&lt;a href=&quot;#cb1-25&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-26&quot;&gt;&lt;a href=&quot;#cb1-26&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;main &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; defaultMainWithIngredients ings &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-27&quot;&gt;&lt;a href=&quot;#cb1-27&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  askOption &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; \(&lt;span class=&quot;dt&quot;&gt;BuildBot&lt;/span&gt; bb) &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-28&quot;&gt;&lt;a href=&quot;#cb1-28&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  testGroup &lt;span class=&quot;st&quot;&gt;&amp;quot;Tests&amp;quot;&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-29&quot;&gt;&lt;a href=&quot;#cb1-29&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  [ testCase &lt;span class=&quot;st&quot;&gt;&amp;quot;Successful test&amp;quot;&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;return&lt;/span&gt; () ] &lt;span class=&quot;op&quot;&gt;++&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-30&quot;&gt;&lt;a href=&quot;#cb1-30&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;if&lt;/span&gt; bb&lt;/span&gt;
&lt;span id=&quot;cb1-31&quot;&gt;&lt;a href=&quot;#cb1-31&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;kw&quot;&gt;then&lt;/span&gt; []&lt;/span&gt;
&lt;span id=&quot;cb1-32&quot;&gt;&lt;a href=&quot;#cb1-32&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;kw&quot;&gt;else&lt;/span&gt; [ testCase &lt;span class=&quot;st&quot;&gt;&amp;quot;Failing test&amp;quot;&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; assertFailure &lt;span class=&quot;st&quot;&gt;&amp;quot;build bot&amp;quot;&lt;/span&gt; ]&lt;/span&gt;
&lt;span id=&quot;cb1-33&quot;&gt;&lt;a href=&quot;#cb1-33&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-34&quot;&gt;&lt;a href=&quot;#cb1-34&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    ings &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-35&quot;&gt;&lt;a href=&quot;#cb1-35&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      includingOptions [&lt;span class=&quot;dt&quot;&gt;Option&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;Proxy&lt;/span&gt;&lt;span class=&quot;ot&quot;&gt; ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Proxy&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;BuildBot&lt;/span&gt;)] &lt;span class=&quot;op&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-36&quot;&gt;&lt;a href=&quot;#cb1-36&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      defaultIngredients&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;controlling-the-depth&quot;&gt;Controlling the depth&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;When running the tests is there any general solution to set the
&lt;code&gt;Depth&lt;/code&gt; parameter for the (individual) tests, or better yet,
a fine grained solution to set the &lt;code&gt;Depth&lt;/code&gt; parameter for
individual fields? — &lt;a
href=&quot;http://stackoverflow.com/q/20582795/110081&quot;&gt;jules&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Not that I recommend doing this — see &lt;a
href=&quot;http://stackoverflow.com/a/20469204/110081&quot;&gt;this answer&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;But here’s how you can do it if you’re sure you want it.&lt;/p&gt;
&lt;p&gt;(This was also possible to hack with earlier versions of Tasty — see
&lt;a href=&quot;https://gist.github.com/UnkindPartition/7961850&quot;&gt;this
gist&lt;/a&gt;).&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb2&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb2-1&quot;&gt;&lt;a href=&quot;#cb2-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;{-# LANGUAGE DeriveDataTypeable #-}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-2&quot;&gt;&lt;a href=&quot;#cb2-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-3&quot;&gt;&lt;a href=&quot;#cb2-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Test.Tasty&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-4&quot;&gt;&lt;a href=&quot;#cb2-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Test.Tasty.Options&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-5&quot;&gt;&lt;a href=&quot;#cb2-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Test.Tasty.SmallCheck&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-6&quot;&gt;&lt;a href=&quot;#cb2-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Test.SmallCheck.Series&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-7&quot;&gt;&lt;a href=&quot;#cb2-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Control.Applicative&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-8&quot;&gt;&lt;a href=&quot;#cb2-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Data.Proxy&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-9&quot;&gt;&lt;a href=&quot;#cb2-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Data.Typeable&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-10&quot;&gt;&lt;a href=&quot;#cb2-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-11&quot;&gt;&lt;a href=&quot;#cb2-11&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;T1&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;T1&lt;/span&gt; {&lt;span class=&quot;ot&quot;&gt; p1 ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Int&lt;/span&gt;,&lt;/span&gt;
&lt;span id=&quot;cb2-12&quot;&gt;&lt;a href=&quot;#cb2-12&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;               p2 ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Char&lt;/span&gt;,&lt;/span&gt;
&lt;span id=&quot;cb2-13&quot;&gt;&lt;a href=&quot;#cb2-13&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;               p3 ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Int&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-14&quot;&gt;&lt;a href=&quot;#cb2-14&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;             } &lt;span class=&quot;kw&quot;&gt;deriving&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;Eq&lt;/span&gt;, &lt;span class=&quot;dt&quot;&gt;Show&lt;/span&gt;)&lt;/span&gt;
&lt;span id=&quot;cb2-15&quot;&gt;&lt;a href=&quot;#cb2-15&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-16&quot;&gt;&lt;a href=&quot;#cb2-16&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;newtype&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;P1Depth&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;P1Depth&lt;/span&gt; {&lt;span class=&quot;ot&quot;&gt; getP1Depth ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Int&lt;/span&gt; }&lt;/span&gt;
&lt;span id=&quot;cb2-17&quot;&gt;&lt;a href=&quot;#cb2-17&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;deriving&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Typeable&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-18&quot;&gt;&lt;a href=&quot;#cb2-18&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-19&quot;&gt;&lt;a href=&quot;#cb2-19&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;instance&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;IsOption&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;P1Depth&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-20&quot;&gt;&lt;a href=&quot;#cb2-20&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  defaultValue &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;P1Depth&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;5&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-21&quot;&gt;&lt;a href=&quot;#cb2-21&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  parseValue &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;fmap&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;P1Depth&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt; safeRead&lt;/span&gt;
&lt;span id=&quot;cb2-22&quot;&gt;&lt;a href=&quot;#cb2-22&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  optionName &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;quot;smallcheck-depth-p1&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-23&quot;&gt;&lt;a href=&quot;#cb2-23&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  optionHelp &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;quot;Depth to use for p1&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-24&quot;&gt;&lt;a href=&quot;#cb2-24&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-25&quot;&gt;&lt;a href=&quot;#cb2-25&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;t1Series&lt;/span&gt;
&lt;span id=&quot;cb2-26&quot;&gt;&lt;a href=&quot;#cb2-26&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;  ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Monad&lt;/span&gt; m&lt;/span&gt;
&lt;span id=&quot;cb2-27&quot;&gt;&lt;a href=&quot;#cb2-27&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;ot&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Int&lt;/span&gt; &lt;span class=&quot;co&quot;&gt;-- depth of p1&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-28&quot;&gt;&lt;a href=&quot;#cb2-28&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Series&lt;/span&gt; m &lt;span class=&quot;dt&quot;&gt;T1&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-29&quot;&gt;&lt;a href=&quot;#cb2-29&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;t1Series d &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; decDepth &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-30&quot;&gt;&lt;a href=&quot;#cb2-30&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;dt&quot;&gt;T1&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;&amp;lt;$&amp;gt;&lt;/span&gt; localDepth (&lt;span class=&quot;fu&quot;&gt;const&lt;/span&gt; d) series &lt;span class=&quot;op&quot;&gt;&amp;lt;~&amp;gt;&lt;/span&gt; series &lt;span class=&quot;op&quot;&gt;&amp;lt;~&amp;gt;&lt;/span&gt; series&lt;/span&gt;
&lt;span id=&quot;cb2-31&quot;&gt;&lt;a href=&quot;#cb2-31&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-32&quot;&gt;&lt;a href=&quot;#cb2-32&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;main ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;IO&lt;/span&gt; ()&lt;/span&gt;
&lt;span id=&quot;cb2-33&quot;&gt;&lt;a href=&quot;#cb2-33&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;main &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; defaultMainWithIngredients (optsIng &lt;span class=&quot;op&quot;&gt;:&lt;/span&gt; defaultIngredients) &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-34&quot;&gt;&lt;a href=&quot;#cb2-34&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  askOption &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; \(&lt;span class=&quot;dt&quot;&gt;P1Depth&lt;/span&gt; p1d) &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-35&quot;&gt;&lt;a href=&quot;#cb2-35&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    testProperty &lt;span class=&quot;st&quot;&gt;&amp;quot;Test1&amp;quot;&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-36&quot;&gt;&lt;a href=&quot;#cb2-36&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      over (t1Series p1d) &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-37&quot;&gt;&lt;a href=&quot;#cb2-37&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;        \x &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; x &lt;span class=&quot;op&quot;&gt;==&lt;/span&gt; x&lt;/span&gt;
&lt;span id=&quot;cb2-38&quot;&gt;&lt;a href=&quot;#cb2-38&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-39&quot;&gt;&lt;a href=&quot;#cb2-39&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    optsIng &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; includingOptions [&lt;span class=&quot;dt&quot;&gt;Option&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;Proxy&lt;/span&gt;&lt;span class=&quot;ot&quot;&gt; ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Proxy&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;P1Depth&lt;/span&gt;)]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;To increase the depth of &lt;code&gt;p1&lt;/code&gt; to 20, pass
&lt;code&gt;--smallcheck-depth-p1 20&lt;/code&gt; on the command line.&lt;/p&gt;
</description>
                        <pubDate>Fri, 20 Dec 2013 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2013-12-20-tasty-custom-options</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2013-12-20-tasty-custom-options.html</guid>
                </item>
        
                <item>
                        <title>On column positions in vim</title>
                        <description>&lt;p&gt;This post describes some of my findings about how locations
(specifically, column positions) work in vim. My interest in this
originated from the work on &lt;a
href=&quot;https://github.com/UnkindPartition/ariadne-vim&quot;&gt;ariadne-vim&lt;/a&gt;, a
TAGS-like plugin for vim.&lt;/p&gt;
&lt;p&gt;ariadne-vim works by sending source locations back and forth to
ariadne, the server process that does all the intellectual work —
parsing and resolving the code. Those source locations had better be
computed identically on the server side and the vim side.&lt;/p&gt;
&lt;h2 id=&quot;byte-offsets-columns&quot;&gt;Byte offsets («columns»)&lt;/h2&gt;
&lt;p&gt;The main way column positions are represented in vim is by byte
offsets. That’s what functions like &lt;code&gt;getpos&lt;/code&gt;,
&lt;code&gt;col&lt;/code&gt;, and &lt;code&gt;cursor&lt;/code&gt; work with.&lt;/p&gt;
&lt;p&gt;As an example, consider the following code:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb1&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb1-1&quot;&gt;&lt;a href=&quot;#cb1-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;data&lt;/span&gt;    &lt;span class=&quot;dt&quot;&gt;Maybe&lt;/span&gt; α &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Just&lt;/span&gt; α &lt;span class=&quot;op&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Nothing&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;To make things interesting, I used a Greek variable name and put a
tab after &lt;code&gt;data&lt;/code&gt;. These two things — multibyte characters and
tabs — are what we will be concerned with.&lt;/p&gt;
&lt;p&gt;So, let’s calculate the byte offset of the capital N in
&lt;code&gt;Nothing&lt;/code&gt;. The tab is just one byte. The Greek alpha, on the
other hand… may occupy any number of bytes, depending on the encoding
being used.&lt;/p&gt;
&lt;p&gt;Assuming the UTF-8 encoding, where alpha occupies two bytes, the byte
offset of N is 27. But if the file was encoded using &lt;a
href=&quot;https://en.wikipedia.org/wiki/ISO/IEC_8859-7&quot;&gt;ISO/IEC 8859-7&lt;/a&gt;,
where alpha is just one byte, then, as seen by vim, the position would
be… still 27. That’s because besides the file encoding (as specified by
the &lt;code&gt;fileencoding&lt;/code&gt; option) vim also has its own internal
encoding (the &lt;code&gt;encoding&lt;/code&gt; option), and that’s what is used to
compute those byte offsets.&lt;/p&gt;
&lt;p&gt;The internal encoding is global for vim (unlike the file encoding,
which is local to buffers) and is typically set after the locale’s
encoding.&lt;/p&gt;
&lt;p&gt;Isn’t it great that byte offsets do not depend on file encodings? Not
at all. It means that you cannot simply compute offsets externally just
by counting bytes in the file. Instead, you have to decode the file
using &lt;code&gt;fileencoding&lt;/code&gt;, and then re-encode it using
&lt;code&gt;encoding&lt;/code&gt; — and of course you need to know what those
encodings are!&lt;/p&gt;
&lt;p&gt;Besides, the parser used by the server process, haskell-src-exts,
computes all locations as characters, not bytes. It would be nice if we
didn’t have to perform tricky conversions on those locations.&lt;/p&gt;
&lt;h2 id=&quot;virtual-columns&quot;&gt;Virtual columns&lt;/h2&gt;
&lt;p&gt;Virtual column of a position is where on the screen that position
actually occurs. It can be obtained using the &lt;code&gt;virtcol&lt;/code&gt;
function. It’s much closer to the character count than the ordinary
column (the byte offset), because even if a character is multibyte, it
still takes one column on the screen. (I’m going to ignore combining
characters here.)&lt;/p&gt;
&lt;p&gt;The tabs are also interpreted differently by &lt;code&gt;virtcol&lt;/code&gt;.
They occupy variable number of columns — just as they do on the screen!
For ariadne it’s a good thing, actually, because the column numbers are
computed by the haskell-src-exts parser in the same way, using the tab
stops placed every 8 characters.&lt;/p&gt;
&lt;p&gt;In our example with &lt;code&gt;Maybe&lt;/code&gt; above, the position of N is
28, and the position of M in &lt;code&gt;Maybe&lt;/code&gt; is 9, because it comes
after the tab character and the preceding text is shorter than 8
characters. (This is all assuming the tab stop size of 8.)&lt;/p&gt;
&lt;p&gt;The only issue is that &lt;code&gt;virtcol&lt;/code&gt; is computed based on the
current value of the &lt;code&gt;ts&lt;/code&gt; option, which specifies the tab
stop size. Generally speaking, users may have any value of
&lt;code&gt;ts&lt;/code&gt;, while the Haskell report specifies that the tab stop
size is 8, and haskell-src-exts computes locations based on that.&lt;/p&gt;
&lt;p&gt;So, in ariadne-vim I temporarily set &lt;code&gt;ts&lt;/code&gt; to 8 characters.
Initially I was concerned that this will lead to screen flickering,
because every time we change the &lt;code&gt;ts&lt;/code&gt; value, vim reformats
the buffer accordingly. But an experiment revealed that it is done after
the full command is completed. As soon as we restore the ts value in the
same command, the user won’t notice anything. It’s a hack, but the
proper alternative — converting positions to byte counts on the server
side — is very complicated.&lt;/p&gt;
&lt;p&gt;That’s how we query the current position. How do we jump to a
different one? Fortunately, the &lt;code&gt;|&lt;/code&gt; motion operates with
virtual columns, so we use that. We cannot use the &lt;code&gt;cursor&lt;/code&gt;
function, which deals with byte counts. And, of course, &lt;code&gt;|&lt;/code&gt;
is also sensitive to the value of &lt;code&gt;ts&lt;/code&gt;, which again has to be
modified temporarily.&lt;/p&gt;
&lt;h2 id=&quot;credits&quot;&gt;Credits&lt;/h2&gt;
&lt;p&gt;Thanks to Ingo Karkat for &lt;a
href=&quot;http://stackoverflow.com/a/20397048/110081&quot;&gt;explaining&lt;/a&gt; the
situation to me.&lt;/p&gt;
</description>
                        <pubDate>Sat, 14 Dec 2013 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2013-12-14-vim-positions</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2013-12-14-vim-positions.html</guid>
                </item>
        
                <item>
                        <title>Resources in Tasty</title>
                        <description>&lt;p&gt;This article explores the new feature of the &lt;a
href=&quot;http://documentup.com/feuerbach/tasty&quot;&gt;Tasty&lt;/a&gt; test framework —
&lt;a
href=&quot;https://hackage.haskell.org/package/tasty-0.5.1/docs/Test-Tasty.html#g:4&quot;&gt;resources&lt;/a&gt;.
It was added in the version 0.5 (and got a small fix in &lt;a
href=&quot;https://hackage.haskell.org/package/tasty-0.5.1&quot;&gt;0.5.1&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt; this post conveys the general idea about
resources, but in later versions of tasty (starting from 0.7), the API
is a bit different. To learn more, see &lt;a
href=&quot;2013-12-29-tasty-resources-2&quot;&gt;this subsequent article&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;what-problem-it-solves&quot;&gt;What problem it solves&lt;/h2&gt;
&lt;p&gt;Often a group of tests need access to a common resource, such as a
connection over which they make requests, or a temporary directory in
which they create files. When the tests are done, the resource should be
released (the connection should be closed, the directory should be
removed).&lt;/p&gt;
&lt;p&gt;Previously, allocation of the resource could be performed outside of
tasty like this:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb1&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb1-1&quot;&gt;&lt;a href=&quot;#cb1-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Test.Tasty&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Tasty&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-2&quot;&gt;&lt;a href=&quot;#cb1-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Control.Exception&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-3&quot;&gt;&lt;a href=&quot;#cb1-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-4&quot;&gt;&lt;a href=&quot;#cb1-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;main &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-5&quot;&gt;&lt;a href=&quot;#cb1-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  bracket acquire release &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; \resource &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-6&quot;&gt;&lt;a href=&quot;#cb1-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    Tasty.defaultMain &lt;span class=&quot;op&quot;&gt;...&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This solution, however, has several problems.&lt;/p&gt;
&lt;p&gt;First, the resource is initialized in the beginning and released at
the very end. Depending on the kind of resource we’re grabbing, this may
be inconvenient or even infeasible.&lt;/p&gt;
&lt;p&gt;Second, not all modes of running the test suite involve actually
running the tests — like, for instance, &lt;code&gt;--help&lt;/code&gt; or
&lt;code&gt;--list-tests&lt;/code&gt;. But because we’re acquiring the resource
outside of tasty, we have no way to know that it’s not necessary.&lt;/p&gt;
&lt;p&gt;A similar problem occurs when we do run tests, but not all of them.
Remember, we can choose which tests to run with the
&lt;code&gt;--pattern&lt;/code&gt; option. Maybe for the tests we want to run right
now that expensive resource isn’t needed, but again, we can’t know
that.&lt;/p&gt;
&lt;p&gt;So, to avoid these kinds of problems, special support for resources
has been introduced.&lt;/p&gt;
&lt;h2 id=&quot;how-to-use-it&quot;&gt;How to use it&lt;/h2&gt;
&lt;p&gt;There’s just one new function you need to be aware of, and its
signature is very simple:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb2&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb2-1&quot;&gt;&lt;a href=&quot;#cb2-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;withResource&lt;/span&gt;
&lt;span id=&quot;cb2-2&quot;&gt;&lt;a href=&quot;#cb2-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;  ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;IO&lt;/span&gt; a         &lt;span class=&quot;co&quot;&gt;-- acquire resource&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-3&quot;&gt;&lt;a href=&quot;#cb2-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; (a &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;IO&lt;/span&gt; ()) &lt;span class=&quot;co&quot;&gt;-- release resource&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-4&quot;&gt;&lt;a href=&quot;#cb2-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;TestTree&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-5&quot;&gt;&lt;a href=&quot;#cb2-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;TestTree&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;withResouce&lt;/code&gt; annotates a &lt;code&gt;TestTree&lt;/code&gt; (typically
that will be a &lt;code&gt;testGroup&lt;/code&gt;) with the actions that should be
run before and after the tests, respectively.&lt;/p&gt;
&lt;p&gt;Note the similarity to the &lt;code&gt;bracket&lt;/code&gt; function from
&lt;code&gt;Control.Exception&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb3&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb3-1&quot;&gt;&lt;a href=&quot;#cb3-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;bracket&lt;/span&gt;
&lt;span id=&quot;cb3-2&quot;&gt;&lt;a href=&quot;#cb3-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;  ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;IO&lt;/span&gt; a         &lt;span class=&quot;co&quot;&gt;-- computation to run first (&amp;quot;acquire resource&amp;quot;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-3&quot;&gt;&lt;a href=&quot;#cb3-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; (a &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;IO&lt;/span&gt; b)  &lt;span class=&quot;co&quot;&gt;-- computation to run last (&amp;quot;release resource&amp;quot;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-4&quot;&gt;&lt;a href=&quot;#cb3-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; (a &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;IO&lt;/span&gt; c)  &lt;span class=&quot;co&quot;&gt;-- computation to run in-between&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-5&quot;&gt;&lt;a href=&quot;#cb3-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;IO&lt;/span&gt; c         &lt;span class=&quot;co&quot;&gt;-- returns the value from the in-between computation&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;A major difference, however, is that the third argument of
&lt;code&gt;withResource&lt;/code&gt; isn’t a function and doesn’t have direct
access to the resource.&lt;/p&gt;
&lt;p&gt;Sometimes it’s not a big deal — if you create a temporary directory
with a known name, then you just have to know it’s there.&lt;/p&gt;
&lt;p&gt;But often you do need to access the resource from the tests. In that
case, use an &lt;code&gt;IORef&lt;/code&gt; (created outside of tasty) to store the
resource once it’s initialized. Here’s an example from the docs:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb4&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb4-1&quot;&gt;&lt;a href=&quot;#cb4-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Test.Tasty&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-2&quot;&gt;&lt;a href=&quot;#cb4-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Test.Tasty.HUnit&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-3&quot;&gt;&lt;a href=&quot;#cb4-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Data.IORef&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-4&quot;&gt;&lt;a href=&quot;#cb4-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-5&quot;&gt;&lt;a href=&quot;#cb4-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;co&quot;&gt;-- assumed defintions&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-6&quot;&gt;&lt;a href=&quot;#cb4-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Foo&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-7&quot;&gt;&lt;a href=&quot;#cb4-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;acquire ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;IO&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Foo&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-8&quot;&gt;&lt;a href=&quot;#cb4-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;release ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Foo&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;IO&lt;/span&gt; ()&lt;/span&gt;
&lt;span id=&quot;cb4-9&quot;&gt;&lt;a href=&quot;#cb4-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;testWithFoo ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Foo&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Assertion&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-10&quot;&gt;&lt;a href=&quot;#cb4-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-11&quot;&gt;&lt;a href=&quot;#cb4-11&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;main &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-12&quot;&gt;&lt;a href=&quot;#cb4-12&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  ref &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; newIORef &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-13&quot;&gt;&lt;a href=&quot;#cb4-13&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;co&quot;&gt;-- If you get this error, then either you forgot to actually write to&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-14&quot;&gt;&lt;a href=&quot;#cb4-14&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;co&quot;&gt;-- the IORef, or it&amp;#39;s a bug in tasty&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-15&quot;&gt;&lt;a href=&quot;#cb4-15&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;fu&quot;&gt;error&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;quot;Resource isn&amp;#39;t accessible&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-16&quot;&gt;&lt;a href=&quot;#cb4-16&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  defaultMain &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-17&quot;&gt;&lt;a href=&quot;#cb4-17&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    withResource (&lt;span class=&quot;kw&quot;&gt;do&lt;/span&gt; r &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; acquire; writeIORef ref r; &lt;span class=&quot;fu&quot;&gt;return&lt;/span&gt; r) release (tests ref)&lt;/span&gt;
&lt;span id=&quot;cb4-18&quot;&gt;&lt;a href=&quot;#cb4-18&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-19&quot;&gt;&lt;a href=&quot;#cb4-19&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;tests ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;IORef&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Foo&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;TestTree&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-20&quot;&gt;&lt;a href=&quot;#cb4-20&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;tests ref &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-21&quot;&gt;&lt;a href=&quot;#cb4-21&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  testGroup &lt;span class=&quot;st&quot;&gt;&amp;quot;Tests&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-22&quot;&gt;&lt;a href=&quot;#cb4-22&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    [ testCase &lt;span class=&quot;st&quot;&gt;&amp;quot;x&amp;quot;&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; readIORef ref &lt;span class=&quot;op&quot;&gt;&amp;gt;&amp;gt;=&lt;/span&gt; testWithFoo&lt;/span&gt;
&lt;span id=&quot;cb4-23&quot;&gt;&lt;a href=&quot;#cb4-23&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    ]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Yeah, perhaps not the most elegant way to pass the resource around,
but it’s simple and gets the job done.&lt;/p&gt;
&lt;p&gt;In the next section I’ll explain why it’s done in this way.&lt;/p&gt;
&lt;h2 id=&quot;alternative-designs&quot;&gt;Alternative designs&lt;/h2&gt;
&lt;h3 id=&quot;test-frameworks-way&quot;&gt;test-framework’s way&lt;/h3&gt;
&lt;p&gt;test-framework allows generating tests in the IO monad using the
function&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb5&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb5-1&quot;&gt;&lt;a href=&quot;#cb5-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;buildTest ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;IO&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Test&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Test&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This solves the first problem described in the beginning of this
article, but not the second one. Indeed, if we want list all the tests,
or perform some other action on them without actually running them, we
still have to execute the IO action and acquire the resources
unnecessarily.&lt;/p&gt;
&lt;h3 id=&quot;bracket-way&quot;&gt;bracket way&lt;/h3&gt;
&lt;p&gt;Due to the exact same reason we can’t mimic the &lt;code&gt;bracket&lt;/code&gt;
function and pass the resource to the tests like this&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb6&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb6-1&quot;&gt;&lt;a href=&quot;#cb6-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;withResource&lt;/span&gt;
&lt;span id=&quot;cb6-2&quot;&gt;&lt;a href=&quot;#cb6-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;  ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;IO&lt;/span&gt; a&lt;/span&gt;
&lt;span id=&quot;cb6-3&quot;&gt;&lt;a href=&quot;#cb6-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; (a &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;IO&lt;/span&gt; ())&lt;/span&gt;
&lt;span id=&quot;cb6-4&quot;&gt;&lt;a href=&quot;#cb6-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; (a &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;TestTree&lt;/span&gt;)&lt;/span&gt;
&lt;span id=&quot;cb6-5&quot;&gt;&lt;a href=&quot;#cb6-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;TestTree&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Again, to list the tests we’d have to perform the IO action. Or, when
in non-running mode, we could pass
&lt;code&gt;error &quot;Don&apos;t evaluate the resource in non-running mode&quot;&lt;/code&gt; as
an &lt;code&gt;a&lt;/code&gt;. This last option may actually be not as bad — I’d be
interested in what others think.&lt;/p&gt;
&lt;p&gt;A hypocritical variation of this would be to replace
&lt;code&gt;a -&amp;gt; TestTree&lt;/code&gt; with &lt;code&gt;Maybe a -&amp;gt; TestTree&lt;/code&gt;,
and pass &lt;code&gt;Nothing&lt;/code&gt; when in non-running mode. I call it
hypocritical because the user still would have to use
&lt;code&gt;fromJust&lt;/code&gt; or a similar partial function to get the resource,
but on our side it looks like everything is total. Pro: reminds the user
that the resource may not be there and should not be accessed unless
we’re running. Con: boilerplate pattern-matching on the resource.&lt;/p&gt;
&lt;h3 id=&quot;type-safe-way&quot;&gt;Type-safe way&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;a -&amp;gt; TestTree&lt;/code&gt; is not the only way to indicate that a
test tree depends on the resource.&lt;/p&gt;
&lt;p&gt;We could use type-level tricks similar to &lt;a
href=&quot;http://hackage.haskell.org/package/extensible-effects&quot;&gt;extensible-effects&lt;/a&gt;
or &lt;a href=&quot;http://hackage.haskell.org/package/regions&quot;&gt;regions&lt;/a&gt; to
record which resources can be accessed by tests. I decided not to do
this, because such things make code harder to understand and generally
confuse users.&lt;/p&gt;
&lt;p&gt;In addition, the problem described in the next section,
«Non-type-safe way», applies to any type-safe solution, too.&lt;/p&gt;
&lt;h3 id=&quot;non-type-safe-way&quot;&gt;Non-type-safe way&lt;/h3&gt;
&lt;p&gt;Even without compile-time guarantee that the resources are acquired
and of the right type, we still could automate the &lt;code&gt;IORef&lt;/code&gt;
business and store resources in a data structure like
&lt;code&gt;Map ResourceName Dynamic&lt;/code&gt;. We could then provide a monadic
interface to accessing the properties, such as&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb7&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb7-1&quot;&gt;&lt;a href=&quot;#cb7-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;getResource ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Typeable&lt;/span&gt; a &lt;span class=&quot;ot&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;ResourceName&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;TestM&lt;/span&gt; a&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;But then we’d have to teach every test provider how to run tests in
our &lt;code&gt;TestM&lt;/code&gt; monad. In some cases (HUnit) this is just not
possible. On the other hand, all test providers seem to support running
simple IO actions inside tests.&lt;/p&gt;
&lt;h2 id=&quot;a-note-on-parallelism&quot;&gt;A note on parallelism&lt;/h2&gt;
&lt;p&gt;There are two possible reasons to share a resource across multiple
tests. It could be an optimization (to avoid creating and destroying the
resource for every single test), or it could be a semantic requirement.
In the latter case, one might want not to enable parallelism to avoid
tests running simultaneously or in the wrong order.&lt;/p&gt;
&lt;p&gt;While it’s possible to use a &lt;code&gt;TVar&lt;/code&gt; to ensure ordering of
the tests, that would hurt actual parallelism. Tasty can’t know that the
test waits on a &lt;code&gt;TVar&lt;/code&gt; instead of running, so it won’t be
executing other tests during that time either.&lt;/p&gt;
</description>
                        <pubDate>Tue, 10 Dec 2013 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2013-12-10-tasty-resources</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2013-12-10-tasty-resources.html</guid>
                </item>
        
                <item>
                        <title>Why PVP doesn&apos;t work</title>
                        <description>&lt;p&gt;The &lt;a
href=&quot;http://www.haskell.org/haskellwiki/Package_versioning_policy&quot;&gt;Package
versioning policy&lt;/a&gt; is one of the controversial topics in the Haskell
community. Specifically, the point of disagreement is the upper bounds
on dependency versions. Some people consider them necessary, while
others consider them harmful.&lt;/p&gt;
&lt;p&gt;To remind the arguments of both parties, here’s a typical
conversation between a proponent and an opponent of upper bounds:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;pro-pvp&lt;/strong&gt;: A major version change indicates
incompatible changes in the API. Your package could fail to compile
against that new version!&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;against-pvp&lt;/strong&gt;: Well, it &lt;em&gt;could&lt;/em&gt; fail, but most
of the time it doesn’t, because it uses only 10% of the package’s
functionality, and the incompatible change affects some other 5% of the
API.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;pro-pvp&lt;/strong&gt;: Why take chances? If you pin down the
versions with which you have tested your package, you know it will
always compile, no matter which new versions will be released in the
future.&lt;/p&gt;
&lt;p&gt;I belong to the opponents of upper bounds. Instead, I simply make
sure my packages work with the latest everything. This is similar to the
&lt;a
href=&quot;https://github.com/fpco/stackage/wiki/Maintainers-Agreement&quot;&gt;Stackage
philosophy&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I said «simply», while in practice this can be somewhat
time-consuming, given the pace at which the language and libraries
evolve. People have complained in the past that maintaining a Haskell
package is like shooting a moving target.&lt;/p&gt;
&lt;p&gt;But that’s the only way it’s going to work. Below are two reasons why
the alternative — enforcing upper version bounds — doesn’t work.&lt;/p&gt;
&lt;h2 id=&quot;reason-1-incompatible-constraints&quot;&gt;Reason 1 — incompatible
constraints&lt;/h2&gt;
&lt;p&gt;Consider this situation:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;package-a&lt;/code&gt; depends on
&lt;code&gt;containers ==0.4.*&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;package-b&lt;/code&gt; depends on
&lt;code&gt;containers ==0.5.*&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;It’s great that I can compile both of these packages, but what’s the
point if I cannot use them together in my application?&lt;/p&gt;
&lt;p&gt;Interval constraints do not compose — the intersection of non-empty
intervals may be empty. Having just the lower bounds is much better — if
each one of them is satisfiable, then they all can be satisfied
simultaneously (e.g. by the latest version).&lt;/p&gt;
&lt;h2 id=&quot;reason-2-you-cant-nail-everything-down&quot;&gt;Reason 2 — you can’t
nail everything down&lt;/h2&gt;
&lt;p&gt;In theory, you pin down every dependency and in five years from now
it’s going to build in the same way as it just did today.&lt;/p&gt;
&lt;p&gt;In practice, people would want to build your package with modern
compilers, on modern operating systems, and with external libraries
provided by their distributions. These external changes, which you
cannot control, will likely cause some of your dependencies to stop
building in the future.&lt;/p&gt;
&lt;p&gt;To give you a specific example, at some point GHC became more strict
(and rightly so) about type synonym instance declarations.&lt;/p&gt;
&lt;p&gt;This code&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb1&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb1-1&quot;&gt;&lt;a href=&quot;#cb1-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;{-# LANGUAGE TypeSynonymInstances #-}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-2&quot;&gt;&lt;a href=&quot;#cb1-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-3&quot;&gt;&lt;a href=&quot;#cb1-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;C&lt;/span&gt; a&lt;/span&gt;
&lt;span id=&quot;cb1-4&quot;&gt;&lt;a href=&quot;#cb1-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-5&quot;&gt;&lt;a href=&quot;#cb1-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;instance&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;C&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;String&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;compiles with GHC 7.0, but GHC 7.2 requires also to enable
&lt;code&gt;FlexibleInstances&lt;/code&gt;, because it’s needed when you expand the
synonym.&lt;/p&gt;
&lt;p&gt;Every maintained package which has this problem would sooner or later
get the fix, but probably only the latest major version would be fixed.
If you depend on some older version of a problematic package, you won’t
be able to build on anything newer than GHC 7.0.&lt;/p&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;My first argument shows that putting upper dependency bounds can
create obstacles to using your packages, and the second argument shows
that upper bounds in practice don’t deliver on their promise of eternal
buildability.&lt;/p&gt;
&lt;p&gt;So, dear package maintainers, please don’t put the upper bounds on
your dependencies without a specific need.&lt;/p&gt;
&lt;h2 id=&quot;update&quot;&gt;Update&lt;/h2&gt;
&lt;p&gt;Thanks for everyone who responded. You helped me understand the
problem better.&lt;/p&gt;
&lt;p&gt;Turns out there are two separate issues here:&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;Whether to use upper bounds, and&lt;/li&gt;
&lt;li&gt;Whether to support the latest versions of your dependencies.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;They are related in the sense that in order to &lt;em&gt;avoid&lt;/em&gt;
supporting the latest versions of your dependencies you &lt;em&gt;have to&lt;/em&gt;
use upper bounds to keep your library compilable. However, simply using
upper bounds does not mean that you do not support the latest
versions.&lt;/p&gt;
&lt;p&gt;So, my request to the library developers is: please support the
latest versions of your dependencies. Failing to do so (and relying on
upper bounds to have the illustion that it’s fine) is exactly what
causes the problem with incompatible constraints.&lt;/p&gt;
&lt;p&gt;As soon as you support the latest versions of your dependencies,
upper bounds become harmless but also useless.&lt;/p&gt;
&lt;p&gt;They may give you a grace period when a new version of a dependency
comes out, but if you stretch this period, then you’re breaking your
responsibility to support the latest versions.&lt;/p&gt;
&lt;p&gt;On the other hand, having upper bounds puts more strain on you to
keep those bounds up-to-date. Plus, not having upper bounds makes it
more obvious when you don’t actually support the latest versions.&lt;/p&gt;
&lt;p&gt;But at the end, if you are diligent enough, it’s up to you whether to
use upper bounds. My personal choice is still not to put them.&lt;/p&gt;
&lt;p&gt;Also note that this doesn’t apply to application developers (at least
when the application doesn’t support dynamically loaded plugins). In
fact, application developers can compensate for the absence of upper
bounds in their dependencies by putting the constraints in their own
cabal files.&lt;/p&gt;
</description>
                        <pubDate>Sat, 05 Oct 2013 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2013-10-05-why-pvp-doesnt-work</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2013-10-05-why-pvp-doesnt-work.html</guid>
                </item>
        
                <item>
                        <title>Flavours of free applicative functors</title>
                        <description>&lt;p&gt;Six months ago Tom Ellis wrote the article &lt;a
href=&quot;http://web.jaguarpaw.co.uk/~tom/blog/posts/2012-09-09-towards-free-applicatives.html&quot;&gt;Towards
Free Applicatives&lt;/a&gt;, where he described his implementation of a free
applicative functor. In the &lt;a
href=&quot;http://www.reddit.com/r/haskell/comments/zlr0l/towards_free_applicatives/?sort=old&quot;&gt;reddit
discussion&lt;/a&gt; of that article a few more implementations were
suggested.&lt;/p&gt;
&lt;p&gt;In this article I would like to look in more detail how these
implementations work and how they differ from each other.&lt;/p&gt;
&lt;p&gt;The implementations are rewritten in a common style where possible,
to highlight the differences and similarities. Since a picture is worth
a thousand words, for each implementation there’s a diagram showing how
a simple applicative expression
&lt;code&gt;f &amp;lt;$&amp;gt; lift ax &amp;lt;*&amp;gt; lift ay &amp;lt;*&amp;gt; lift az&lt;/code&gt; is
represented.&lt;/p&gt;
&lt;h2 id=&quot;notational-conventions&quot;&gt;Notational conventions&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;x&lt;/code&gt;, &lt;code&gt;y&lt;/code&gt;, &lt;code&gt;z&lt;/code&gt;, &lt;code&gt;f&lt;/code&gt; —
simple (non-functorial) values&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ax&lt;/code&gt;, &lt;code&gt;ay&lt;/code&gt;, &lt;code&gt;az&lt;/code&gt; — values of the
base functor type&lt;/li&gt;
&lt;li&gt;&lt;code&gt;tx&lt;/code&gt;, &lt;code&gt;ty&lt;/code&gt;, &lt;code&gt;tz&lt;/code&gt; — values of the
free applicative functor type&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;on-the-diagrams&quot;&gt;On the diagrams&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;F&lt;/code&gt; — base functor&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Tx&lt;/code&gt;, &lt;code&gt;Ty&lt;/code&gt;, &lt;code&gt;Tz&lt;/code&gt; — inner types of
functorial values (e.g. &lt;code&gt;ax&lt;/code&gt; has type &lt;code&gt;F Tx&lt;/code&gt;). The
function &lt;code&gt;f&lt;/code&gt; has type
&lt;code&gt;Tx -&amp;gt; Ty -&amp;gt; Tz -&amp;gt; Tr&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;A square denotes unit (i.e. &lt;code&gt;()&lt;/code&gt;) as a type, term and
pattern.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;ørjan-johansens-free-applicative&quot;&gt;Ørjan Johansen’s free
applicative&lt;/h2&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb1&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb1-1&quot;&gt;&lt;a href=&quot;#cb1-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Free&lt;/span&gt; f a &lt;span class=&quot;kw&quot;&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-2&quot;&gt;&lt;a href=&quot;#cb1-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;dt&quot;&gt;Pure&lt;/span&gt;&lt;span class=&quot;ot&quot;&gt; ::&lt;/span&gt; a &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Free&lt;/span&gt; f a&lt;/span&gt;
&lt;span id=&quot;cb1-3&quot;&gt;&lt;a href=&quot;#cb1-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;dt&quot;&gt;Ap&lt;/span&gt;&lt;span class=&quot;ot&quot;&gt; ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Free&lt;/span&gt; f (a &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; b) &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; f a &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Free&lt;/span&gt; f b&lt;/span&gt;
&lt;span id=&quot;cb1-4&quot;&gt;&lt;a href=&quot;#cb1-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-5&quot;&gt;&lt;a href=&quot;#cb1-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;instance&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Functor&lt;/span&gt; f &lt;span class=&quot;ot&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Functor&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;Free&lt;/span&gt; f) &lt;span class=&quot;kw&quot;&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-6&quot;&gt;&lt;a href=&quot;#cb1-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;fu&quot;&gt;fmap&lt;/span&gt; f (&lt;span class=&quot;dt&quot;&gt;Pure&lt;/span&gt; x) &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Pure&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; f x&lt;/span&gt;
&lt;span id=&quot;cb1-7&quot;&gt;&lt;a href=&quot;#cb1-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;fu&quot;&gt;fmap&lt;/span&gt; f (&lt;span class=&quot;dt&quot;&gt;Ap&lt;/span&gt; tx ay) &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Ap&lt;/span&gt; ((f &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;) &lt;span class=&quot;op&quot;&gt;&amp;lt;$&amp;gt;&lt;/span&gt; tx) ay&lt;/span&gt;
&lt;span id=&quot;cb1-8&quot;&gt;&lt;a href=&quot;#cb1-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-9&quot;&gt;&lt;a href=&quot;#cb1-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;instance&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Functor&lt;/span&gt; f &lt;span class=&quot;ot&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Applicative&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;Free&lt;/span&gt; f) &lt;span class=&quot;kw&quot;&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-10&quot;&gt;&lt;a href=&quot;#cb1-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;fu&quot;&gt;pure&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Pure&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-11&quot;&gt;&lt;a href=&quot;#cb1-11&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  tx &lt;span class=&quot;op&quot;&gt;&amp;lt;*&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Pure&lt;/span&gt; y &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;fmap&lt;/span&gt; (&lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; y) tx&lt;/span&gt;
&lt;span id=&quot;cb1-12&quot;&gt;&lt;a href=&quot;#cb1-12&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  tx &lt;span class=&quot;op&quot;&gt;&amp;lt;*&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Ap&lt;/span&gt; ty az &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Ap&lt;/span&gt; ((&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;) &lt;span class=&quot;op&quot;&gt;&amp;lt;$&amp;gt;&lt;/span&gt; tx &lt;span class=&quot;op&quot;&gt;&amp;lt;*&amp;gt;&lt;/span&gt; ty) az&lt;/span&gt;
&lt;span id=&quot;cb1-13&quot;&gt;&lt;a href=&quot;#cb1-13&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-14&quot;&gt;&lt;a href=&quot;#cb1-14&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;lift ::&lt;/span&gt; f a &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Free&lt;/span&gt; f a&lt;/span&gt;
&lt;span id=&quot;cb1-15&quot;&gt;&lt;a href=&quot;#cb1-15&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;lift &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Ap&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;Pure&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;id&lt;/span&gt;)&lt;/span&gt;
&lt;span id=&quot;cb1-16&quot;&gt;&lt;a href=&quot;#cb1-16&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-17&quot;&gt;&lt;a href=&quot;#cb1-17&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;lower ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Applicative&lt;/span&gt; f &lt;span class=&quot;ot&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Free&lt;/span&gt; f a &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; f a&lt;/span&gt;
&lt;span id=&quot;cb1-18&quot;&gt;&lt;a href=&quot;#cb1-18&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;lower (&lt;span class=&quot;dt&quot;&gt;Pure&lt;/span&gt; x) &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;pure&lt;/span&gt; x&lt;/span&gt;
&lt;span id=&quot;cb1-19&quot;&gt;&lt;a href=&quot;#cb1-19&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;lower (&lt;span class=&quot;dt&quot;&gt;Ap&lt;/span&gt; tx ay) &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; lower tx &lt;span class=&quot;op&quot;&gt;&amp;lt;*&amp;gt;&lt;/span&gt; ay&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;img src=&quot;/img/freeapp-1.svg&quot; /&gt;&lt;/p&gt;
&lt;p&gt;The tree grows to the left. This can be easily seen on the diagram,
and follows from the fact that the first argument of &lt;code&gt;Ap&lt;/code&gt; is
a free applicative itself and the second is not. (How the tree grows
depends, obviously, on the order of &lt;code&gt;Ap&lt;/code&gt;’s arguments. The
convention here is that &lt;code&gt;Ap&lt;/code&gt;’s arguments are in the
applicative order, so that we can meaningfully talk about the tree’s
associativity.)&lt;/p&gt;
&lt;p&gt;&lt;code&gt;&amp;lt;*&amp;gt;&lt;/code&gt; pattern-matches on its right argument,
effectively re-associating the tree to the left.&lt;/p&gt;
&lt;p&gt;Note that &lt;code&gt;Free f a&lt;/code&gt; is an applicative functor regardless
of &lt;code&gt;f&lt;/code&gt;. It stores &lt;code&gt;f&lt;/code&gt;-values in the tree without
changes. We’ll see later that this is not always the case.&lt;/p&gt;
&lt;h2 id=&quot;twan-van-laarhovens-free-applicative&quot;&gt;Twan van Laarhoven’s free
applicative&lt;/h2&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb2&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb2-1&quot;&gt;&lt;a href=&quot;#cb2-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Free&lt;/span&gt; f a &lt;span class=&quot;kw&quot;&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-2&quot;&gt;&lt;a href=&quot;#cb2-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;dt&quot;&gt;Pure&lt;/span&gt;&lt;span class=&quot;ot&quot;&gt; ::&lt;/span&gt; a &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Free&lt;/span&gt; f a&lt;/span&gt;
&lt;span id=&quot;cb2-3&quot;&gt;&lt;a href=&quot;#cb2-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;dt&quot;&gt;Ap&lt;/span&gt;&lt;span class=&quot;ot&quot;&gt; ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Free&lt;/span&gt; f (a &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; b) &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; f a &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Free&lt;/span&gt; f b&lt;/span&gt;
&lt;span id=&quot;cb2-4&quot;&gt;&lt;a href=&quot;#cb2-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-5&quot;&gt;&lt;a href=&quot;#cb2-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;instance&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Functor&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;Free&lt;/span&gt; f) &lt;span class=&quot;kw&quot;&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-6&quot;&gt;&lt;a href=&quot;#cb2-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;fu&quot;&gt;fmap&lt;/span&gt; f (&lt;span class=&quot;dt&quot;&gt;Pure&lt;/span&gt; x) &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Pure&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; f x&lt;/span&gt;
&lt;span id=&quot;cb2-7&quot;&gt;&lt;a href=&quot;#cb2-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;fu&quot;&gt;fmap&lt;/span&gt; f (&lt;span class=&quot;dt&quot;&gt;Ap&lt;/span&gt; tx ay) &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Ap&lt;/span&gt; ((f &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;) &lt;span class=&quot;op&quot;&gt;&amp;lt;$&amp;gt;&lt;/span&gt; tx) ay&lt;/span&gt;
&lt;span id=&quot;cb2-8&quot;&gt;&lt;a href=&quot;#cb2-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-9&quot;&gt;&lt;a href=&quot;#cb2-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;instance&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Applicative&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;Free&lt;/span&gt; f) &lt;span class=&quot;kw&quot;&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-10&quot;&gt;&lt;a href=&quot;#cb2-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;fu&quot;&gt;pure&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Pure&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-11&quot;&gt;&lt;a href=&quot;#cb2-11&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;dt&quot;&gt;Pure&lt;/span&gt; f &lt;span class=&quot;op&quot;&gt;&amp;lt;*&amp;gt;&lt;/span&gt; tx &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;fmap&lt;/span&gt; f tx&lt;/span&gt;
&lt;span id=&quot;cb2-12&quot;&gt;&lt;a href=&quot;#cb2-12&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;dt&quot;&gt;Ap&lt;/span&gt; tx ay &lt;span class=&quot;op&quot;&gt;&amp;lt;*&amp;gt;&lt;/span&gt; tz &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Ap&lt;/span&gt; (&lt;span class=&quot;fu&quot;&gt;flip&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;&amp;lt;$&amp;gt;&lt;/span&gt; tx &lt;span class=&quot;op&quot;&gt;&amp;lt;*&amp;gt;&lt;/span&gt; tz) ay&lt;/span&gt;
&lt;span id=&quot;cb2-13&quot;&gt;&lt;a href=&quot;#cb2-13&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-14&quot;&gt;&lt;a href=&quot;#cb2-14&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;lift ::&lt;/span&gt; f a &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Free&lt;/span&gt; f a&lt;/span&gt;
&lt;span id=&quot;cb2-15&quot;&gt;&lt;a href=&quot;#cb2-15&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;lift &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Ap&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;Pure&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;id&lt;/span&gt;)&lt;/span&gt;
&lt;span id=&quot;cb2-16&quot;&gt;&lt;a href=&quot;#cb2-16&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-17&quot;&gt;&lt;a href=&quot;#cb2-17&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;lower ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Applicative&lt;/span&gt; f &lt;span class=&quot;ot&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Free&lt;/span&gt; f a &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; f a&lt;/span&gt;
&lt;span id=&quot;cb2-18&quot;&gt;&lt;a href=&quot;#cb2-18&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;lower (&lt;span class=&quot;dt&quot;&gt;Pure&lt;/span&gt; x) &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;pure&lt;/span&gt; x&lt;/span&gt;
&lt;span id=&quot;cb2-19&quot;&gt;&lt;a href=&quot;#cb2-19&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;lower (&lt;span class=&quot;dt&quot;&gt;Ap&lt;/span&gt; tx ay) &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;flip&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;id&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;&amp;lt;$&amp;gt;&lt;/span&gt; ay &lt;span class=&quot;op&quot;&gt;&amp;lt;*&amp;gt;&lt;/span&gt; lower tx&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;img src=&quot;/img/freeapp-2.svg&quot; /&gt;&lt;/p&gt;
&lt;p&gt;This is a variation of Ørjan’s implementation. As can be seen from
the diagrams, the only difference is that it stores the values in the
opposite order, and modifies the function to accept them in that
order.&lt;/p&gt;
&lt;p&gt;As in Ørjan’s implementation, the tree grows to the left, but
&lt;code&gt;&amp;lt;*&amp;gt;&lt;/code&gt; now pattern-matches on its left argument, in
order to push its right argument to the leftmost position in the
tree.&lt;/p&gt;
&lt;p&gt;The way &lt;code&gt;&amp;lt;*&amp;gt;&lt;/code&gt; does pattern matching directly affects
its algorithmic complexity. Ørjan’s implementation is linear in the size
of its right argument and thus works better with left-associated
applicative expressions. Twan’s version is dual: it is linear in the
size of its left argument and works better with right-associated
expressions. In both cases, unfortunate nesting increases complexity
from linear to quadratic.&lt;/p&gt;
&lt;p&gt;Also pay attention to the &lt;code&gt;lower&lt;/code&gt; function. It has to take
care of the effects — the right subtree must be «executed» before the
left subtree in order to restore the original value faithfully.&lt;/p&gt;
&lt;h2 id=&quot;paolo-capriottis-free-applicative&quot;&gt;Paolo Capriotti’s free
applicative&lt;/h2&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb3&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb3-1&quot;&gt;&lt;a href=&quot;#cb3-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Free&lt;/span&gt; f a &lt;span class=&quot;kw&quot;&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-2&quot;&gt;&lt;a href=&quot;#cb3-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;dt&quot;&gt;Pure&lt;/span&gt;&lt;span class=&quot;ot&quot;&gt; ::&lt;/span&gt; a &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Free&lt;/span&gt; f a&lt;/span&gt;
&lt;span id=&quot;cb3-3&quot;&gt;&lt;a href=&quot;#cb3-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;dt&quot;&gt;Ap&lt;/span&gt;&lt;span class=&quot;ot&quot;&gt; ::&lt;/span&gt; f (a &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; b) &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Free&lt;/span&gt; f a &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Free&lt;/span&gt; f b&lt;/span&gt;
&lt;span id=&quot;cb3-4&quot;&gt;&lt;a href=&quot;#cb3-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-5&quot;&gt;&lt;a href=&quot;#cb3-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;instance&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Functor&lt;/span&gt; f &lt;span class=&quot;ot&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Functor&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;Free&lt;/span&gt; f) &lt;span class=&quot;kw&quot;&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-6&quot;&gt;&lt;a href=&quot;#cb3-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;fu&quot;&gt;fmap&lt;/span&gt; f (&lt;span class=&quot;dt&quot;&gt;Pure&lt;/span&gt; x) &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Pure&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; f x&lt;/span&gt;
&lt;span id=&quot;cb3-7&quot;&gt;&lt;a href=&quot;#cb3-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;fu&quot;&gt;fmap&lt;/span&gt; f (&lt;span class=&quot;dt&quot;&gt;Ap&lt;/span&gt; ax ty) &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Ap&lt;/span&gt; (&lt;span class=&quot;fu&quot;&gt;fmap&lt;/span&gt; (f&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;) ax) ty&lt;/span&gt;
&lt;span id=&quot;cb3-8&quot;&gt;&lt;a href=&quot;#cb3-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-9&quot;&gt;&lt;a href=&quot;#cb3-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;instance&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Functor&lt;/span&gt; f &lt;span class=&quot;ot&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Applicative&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;Free&lt;/span&gt; f) &lt;span class=&quot;kw&quot;&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-10&quot;&gt;&lt;a href=&quot;#cb3-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;fu&quot;&gt;pure&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Pure&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-11&quot;&gt;&lt;a href=&quot;#cb3-11&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;dt&quot;&gt;Pure&lt;/span&gt; f &lt;span class=&quot;op&quot;&gt;&amp;lt;*&amp;gt;&lt;/span&gt; tx &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;fmap&lt;/span&gt; f tx&lt;/span&gt;
&lt;span id=&quot;cb3-12&quot;&gt;&lt;a href=&quot;#cb3-12&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;dt&quot;&gt;Ap&lt;/span&gt; ax ty &lt;span class=&quot;op&quot;&gt;&amp;lt;*&amp;gt;&lt;/span&gt; tz &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Ap&lt;/span&gt; (&lt;span class=&quot;fu&quot;&gt;fmap&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;uncurry&lt;/span&gt; ax) ((,) &lt;span class=&quot;op&quot;&gt;&amp;lt;$&amp;gt;&lt;/span&gt; ty &lt;span class=&quot;op&quot;&gt;&amp;lt;*&amp;gt;&lt;/span&gt; tz)&lt;/span&gt;
&lt;span id=&quot;cb3-13&quot;&gt;&lt;a href=&quot;#cb3-13&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-14&quot;&gt;&lt;a href=&quot;#cb3-14&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;lift ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Functor&lt;/span&gt; f &lt;span class=&quot;ot&quot;&gt;=&amp;gt;&lt;/span&gt; f a &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Free&lt;/span&gt; f a&lt;/span&gt;
&lt;span id=&quot;cb3-15&quot;&gt;&lt;a href=&quot;#cb3-15&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;lift ax &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Ap&lt;/span&gt; (&lt;span class=&quot;fu&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;&amp;lt;$&amp;gt;&lt;/span&gt; ax) (&lt;span class=&quot;dt&quot;&gt;Pure&lt;/span&gt; ())&lt;/span&gt;
&lt;span id=&quot;cb3-16&quot;&gt;&lt;a href=&quot;#cb3-16&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb3-17&quot;&gt;&lt;a href=&quot;#cb3-17&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;lower ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Applicative&lt;/span&gt; f &lt;span class=&quot;ot&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Free&lt;/span&gt; f a &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; f a&lt;/span&gt;
&lt;span id=&quot;cb3-18&quot;&gt;&lt;a href=&quot;#cb3-18&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;lower (&lt;span class=&quot;dt&quot;&gt;Pure&lt;/span&gt; x) &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;pure&lt;/span&gt; x&lt;/span&gt;
&lt;span id=&quot;cb3-19&quot;&gt;&lt;a href=&quot;#cb3-19&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;lower (&lt;span class=&quot;dt&quot;&gt;Ap&lt;/span&gt; ax ty) &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; ax &lt;span class=&quot;op&quot;&gt;&amp;lt;*&amp;gt;&lt;/span&gt; lower ty&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;img src=&quot;/img/freeapp-3.svg&quot; /&gt;&lt;/p&gt;
&lt;p&gt;The diagram looks more complicated here. The first thing to notice is
that the tree here grows to the right, unlike in the previous versions.
The actual application of our &lt;code&gt;f&lt;/code&gt; function happens now near
the top of the tree rather than at the bottom. To make that possible,
the function has to be converted to the uncurried form.&lt;/p&gt;
&lt;p&gt;All left nodes except the topmost one are functions (wrapped in the
base functor). All they do is take a nested tuple of the arguments
downstream and add their own value to that tuple. The topmost left node
already knows the final required argument, &lt;code&gt;ax&lt;/code&gt;, and simply
applies the uncurried function to the tuple.&lt;/p&gt;
&lt;p&gt;The functorial values are stored in a modified form, which requires
&lt;code&gt;f&lt;/code&gt; to be an actual &lt;code&gt;Functor&lt;/code&gt;. (But note that any
&lt;code&gt;f&lt;/code&gt; can be turned into a functor using &lt;a
href=&quot;http://hackage.haskell.org/package/kan-extensions/docs/Data-Functor-Yoneda.html&quot;&gt;Yoneda&lt;/a&gt;.)&lt;/p&gt;
&lt;h2 id=&quot;tom-elliss-free-applicative&quot;&gt;Tom Ellis’s free applicative&lt;/h2&gt;
&lt;p&gt;The code here is quite different from the previous versions, so I
decided to reproduce it verbatim (except the &lt;code&gt;lift&lt;/code&gt; and
&lt;code&gt;lower&lt;/code&gt; functions, which I’ve added myself).&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb4&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb4-1&quot;&gt;&lt;a href=&quot;#cb4-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;ChainA&lt;/span&gt; f a b &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Single&lt;/span&gt; (f (a &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; b)) &lt;span class=&quot;op&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;forall&lt;/span&gt; c&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Many&lt;/span&gt; (f (c &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; b)) (&lt;span class=&quot;dt&quot;&gt;ChainA&lt;/span&gt; f a c)&lt;/span&gt;
&lt;span id=&quot;cb4-2&quot;&gt;&lt;a href=&quot;#cb4-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-3&quot;&gt;&lt;a href=&quot;#cb4-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;instance&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Functor&lt;/span&gt; f &lt;span class=&quot;ot&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Functor&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;ChainA&lt;/span&gt; f a) &lt;span class=&quot;kw&quot;&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-4&quot;&gt;&lt;a href=&quot;#cb4-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;fu&quot;&gt;fmap&lt;/span&gt; f (&lt;span class=&quot;dt&quot;&gt;Single&lt;/span&gt; t) &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Single&lt;/span&gt; (&lt;span class=&quot;fu&quot;&gt;fmap&lt;/span&gt; (f &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;) t)&lt;/span&gt;
&lt;span id=&quot;cb4-5&quot;&gt;&lt;a href=&quot;#cb4-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;fu&quot;&gt;fmap&lt;/span&gt; f (&lt;span class=&quot;dt&quot;&gt;Many&lt;/span&gt; g v) &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Many&lt;/span&gt; (&lt;span class=&quot;fu&quot;&gt;fmap&lt;/span&gt; (f &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;) g) v&lt;/span&gt;
&lt;span id=&quot;cb4-6&quot;&gt;&lt;a href=&quot;#cb4-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-7&quot;&gt;&lt;a href=&quot;#cb4-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;chain ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;ChainA&lt;/span&gt; f b c &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;ChainA&lt;/span&gt; f a b &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;ChainA&lt;/span&gt; f a c&lt;/span&gt;
&lt;span id=&quot;cb4-8&quot;&gt;&lt;a href=&quot;#cb4-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;chain (&lt;span class=&quot;dt&quot;&gt;Single&lt;/span&gt; t) v &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Many&lt;/span&gt; t v&lt;/span&gt;
&lt;span id=&quot;cb4-9&quot;&gt;&lt;a href=&quot;#cb4-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;chain (&lt;span class=&quot;dt&quot;&gt;Many&lt;/span&gt; t ts) v &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Many&lt;/span&gt; t (chain ts v)&lt;/span&gt;
&lt;span id=&quot;cb4-10&quot;&gt;&lt;a href=&quot;#cb4-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-11&quot;&gt;&lt;a href=&quot;#cb4-11&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;FreeA&lt;/span&gt; f a &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Pure&lt;/span&gt; a &lt;span class=&quot;op&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;ChainA&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;ChainA&lt;/span&gt; f () a)&lt;/span&gt;
&lt;span id=&quot;cb4-12&quot;&gt;&lt;a href=&quot;#cb4-12&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-13&quot;&gt;&lt;a href=&quot;#cb4-13&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;instance&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Functor&lt;/span&gt; f &lt;span class=&quot;ot&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Functor&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;FreeA&lt;/span&gt; f) &lt;span class=&quot;kw&quot;&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-14&quot;&gt;&lt;a href=&quot;#cb4-14&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;fu&quot;&gt;fmap&lt;/span&gt; f (&lt;span class=&quot;dt&quot;&gt;Pure&lt;/span&gt; a) &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Pure&lt;/span&gt; (f a)&lt;/span&gt;
&lt;span id=&quot;cb4-15&quot;&gt;&lt;a href=&quot;#cb4-15&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;fu&quot;&gt;fmap&lt;/span&gt; f (&lt;span class=&quot;dt&quot;&gt;ChainA&lt;/span&gt; a) &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;ChainA&lt;/span&gt; (&lt;span class=&quot;fu&quot;&gt;fmap&lt;/span&gt; f a)&lt;/span&gt;
&lt;span id=&quot;cb4-16&quot;&gt;&lt;a href=&quot;#cb4-16&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-17&quot;&gt;&lt;a href=&quot;#cb4-17&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;instance&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Functor&lt;/span&gt; f &lt;span class=&quot;ot&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Applicative&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;FreeA&lt;/span&gt; f) &lt;span class=&quot;kw&quot;&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-18&quot;&gt;&lt;a href=&quot;#cb4-18&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;fu&quot;&gt;pure&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Pure&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-19&quot;&gt;&lt;a href=&quot;#cb4-19&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;dt&quot;&gt;Pure&lt;/span&gt; f &lt;span class=&quot;op&quot;&gt;&amp;lt;*&amp;gt;&lt;/span&gt; g &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;fmap&lt;/span&gt; f g&lt;/span&gt;
&lt;span id=&quot;cb4-20&quot;&gt;&lt;a href=&quot;#cb4-20&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    f &lt;span class=&quot;op&quot;&gt;&amp;lt;*&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Pure&lt;/span&gt; g &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;fmap&lt;/span&gt; (&lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; g) f&lt;/span&gt;
&lt;span id=&quot;cb4-21&quot;&gt;&lt;a href=&quot;#cb4-21&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;dt&quot;&gt;ChainA&lt;/span&gt; f &lt;span class=&quot;op&quot;&gt;&amp;lt;*&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;ChainA&lt;/span&gt; g &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;ChainA&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; chain (pullUnit f) g&lt;/span&gt;
&lt;span id=&quot;cb4-22&quot;&gt;&lt;a href=&quot;#cb4-22&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-23&quot;&gt;&lt;a href=&quot;#cb4-23&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;pullUnit ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Functor&lt;/span&gt; f &lt;span class=&quot;ot&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;ChainA&lt;/span&gt; f () (b &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; c) &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;ChainA&lt;/span&gt; f b c&lt;/span&gt;
&lt;span id=&quot;cb4-24&quot;&gt;&lt;a href=&quot;#cb4-24&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;pullUnit &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; removeUnit &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt; pull&lt;/span&gt;
&lt;span id=&quot;cb4-25&quot;&gt;&lt;a href=&quot;#cb4-25&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-26&quot;&gt;&lt;a href=&quot;#cb4-26&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;pass ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Functor&lt;/span&gt; f &lt;span class=&quot;ot&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;ChainA&lt;/span&gt; f a b &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;ChainA&lt;/span&gt; f (a,c) (b,c)&lt;/span&gt;
&lt;span id=&quot;cb4-27&quot;&gt;&lt;a href=&quot;#cb4-27&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;pass (&lt;span class=&quot;dt&quot;&gt;Single&lt;/span&gt; t) &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Single&lt;/span&gt; (&lt;span class=&quot;fu&quot;&gt;fmap&lt;/span&gt; (\f &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; \(a,c) &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; (f a, c)) t)&lt;/span&gt;
&lt;span id=&quot;cb4-28&quot;&gt;&lt;a href=&quot;#cb4-28&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;pass (&lt;span class=&quot;dt&quot;&gt;Many&lt;/span&gt; t ts) &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Many&lt;/span&gt; (&lt;span class=&quot;fu&quot;&gt;fmap&lt;/span&gt; (\f &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; \(a,c) &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; (f a, c)) t) (pass ts)&lt;/span&gt;
&lt;span id=&quot;cb4-29&quot;&gt;&lt;a href=&quot;#cb4-29&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-30&quot;&gt;&lt;a href=&quot;#cb4-30&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;pull ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Functor&lt;/span&gt; f &lt;span class=&quot;ot&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;ChainA&lt;/span&gt; f a (b &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; c) &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;ChainA&lt;/span&gt; f (a,b) c&lt;/span&gt;
&lt;span id=&quot;cb4-31&quot;&gt;&lt;a href=&quot;#cb4-31&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;pull (&lt;span class=&quot;dt&quot;&gt;Single&lt;/span&gt; t) &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Single&lt;/span&gt; (&lt;span class=&quot;fu&quot;&gt;fmap&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;uncurry&lt;/span&gt; t)&lt;/span&gt;
&lt;span id=&quot;cb4-32&quot;&gt;&lt;a href=&quot;#cb4-32&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;pull (&lt;span class=&quot;dt&quot;&gt;Many&lt;/span&gt; t ts) &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Many&lt;/span&gt; (&lt;span class=&quot;fu&quot;&gt;fmap&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;uncurry&lt;/span&gt; t) (pass ts)&lt;/span&gt;
&lt;span id=&quot;cb4-33&quot;&gt;&lt;a href=&quot;#cb4-33&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-34&quot;&gt;&lt;a href=&quot;#cb4-34&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;removeUnit ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Functor&lt;/span&gt; f &lt;span class=&quot;ot&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;ChainA&lt;/span&gt; f ((), a) b &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;ChainA&lt;/span&gt; f a b&lt;/span&gt;
&lt;span id=&quot;cb4-35&quot;&gt;&lt;a href=&quot;#cb4-35&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;removeUnit (&lt;span class=&quot;dt&quot;&gt;Single&lt;/span&gt; t) &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Single&lt;/span&gt; (&lt;span class=&quot;fu&quot;&gt;fmap&lt;/span&gt; (\f &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; \a &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; f ((),a)) t)&lt;/span&gt;
&lt;span id=&quot;cb4-36&quot;&gt;&lt;a href=&quot;#cb4-36&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;removeUnit (&lt;span class=&quot;dt&quot;&gt;Many&lt;/span&gt; t ts) &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Many&lt;/span&gt; t (removeUnit ts)&lt;/span&gt;
&lt;span id=&quot;cb4-37&quot;&gt;&lt;a href=&quot;#cb4-37&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-38&quot;&gt;&lt;a href=&quot;#cb4-38&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;lift ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Functor&lt;/span&gt; f &lt;span class=&quot;ot&quot;&gt;=&amp;gt;&lt;/span&gt; f a &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;FreeA&lt;/span&gt; f a&lt;/span&gt;
&lt;span id=&quot;cb4-39&quot;&gt;&lt;a href=&quot;#cb4-39&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;lift ax &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;ChainA&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Single&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;&amp;lt;$&amp;gt;&lt;/span&gt; ax&lt;/span&gt;
&lt;span id=&quot;cb4-40&quot;&gt;&lt;a href=&quot;#cb4-40&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-41&quot;&gt;&lt;a href=&quot;#cb4-41&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;lower ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Applicative&lt;/span&gt; f &lt;span class=&quot;ot&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;FreeA&lt;/span&gt; f a &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; f a&lt;/span&gt;
&lt;span id=&quot;cb4-42&quot;&gt;&lt;a href=&quot;#cb4-42&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;lower (&lt;span class=&quot;dt&quot;&gt;Pure&lt;/span&gt; x) &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;pure&lt;/span&gt; x&lt;/span&gt;
&lt;span id=&quot;cb4-43&quot;&gt;&lt;a href=&quot;#cb4-43&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;lower (&lt;span class=&quot;dt&quot;&gt;ChainA&lt;/span&gt; chain) &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; lowerChain chain &lt;span class=&quot;op&quot;&gt;&amp;lt;*&amp;gt;&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;pure&lt;/span&gt; ()&lt;/span&gt;
&lt;span id=&quot;cb4-44&quot;&gt;&lt;a href=&quot;#cb4-44&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-45&quot;&gt;&lt;a href=&quot;#cb4-45&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;    lowerChain ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Applicative&lt;/span&gt; f &lt;span class=&quot;ot&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;ChainA&lt;/span&gt; f x y &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; f (x &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; y)&lt;/span&gt;
&lt;span id=&quot;cb4-46&quot;&gt;&lt;a href=&quot;#cb4-46&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    lowerChain (&lt;span class=&quot;dt&quot;&gt;Single&lt;/span&gt; ax) &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; ax&lt;/span&gt;
&lt;span id=&quot;cb4-47&quot;&gt;&lt;a href=&quot;#cb4-47&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    lowerChain (&lt;span class=&quot;dt&quot;&gt;Many&lt;/span&gt; ax ty) &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; (&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt;) &lt;span class=&quot;op&quot;&gt;&amp;lt;$&amp;gt;&lt;/span&gt; ax &lt;span class=&quot;op&quot;&gt;&amp;lt;*&amp;gt;&lt;/span&gt; lowerChain ty&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;img src=&quot;/img/freeapp-4.svg&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Despite the superficial dissimilarity of the code, this is really a
variation on Paolo’s implementation. The only difference is that unit is
not passed as a part of the nested tuples. Two-level types and auxiliary
functions are really just the cost of eliminating that unit.&lt;/p&gt;
&lt;h2 id=&quot;which-one-to-use&quot;&gt;Which one to use?&lt;/h2&gt;
&lt;p&gt;The &lt;a href=&quot;http://hackage.haskell.org/package/free&quot;&gt;free&lt;/a&gt;
package currently uses the Twan’s version, which is the reason of the
reverse effect that I &lt;a
href=&quot;/articles/2013-03-29-gtraverse-vs-gfoldl#remaining-issues&quot;&gt;mentioned&lt;/a&gt;
in the previous article. Edward Kmett points out that the reason for
choosing Twan’s implementation is that you can see the «next
instruction» in O(1) when walking left to right, which is most
common.&lt;/p&gt;
&lt;p&gt;So start with that one, but also look at your problem (how exactly
you are going to analyze the free applicative) and see if any of the
alternatives fit better.&lt;/p&gt;
</description>
                        <pubDate>Sun, 31 Mar 2013 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2013-03-31-flavours-of-free-applicative-functors</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2013-03-31-flavours-of-free-applicative-functors.html</guid>
                </item>
        
                <item>
                        <title>gtraverse vs. gfoldl</title>
                        <description>&lt;p&gt;In &lt;a href=&quot;/articles/2013-03-11-generalizing-gfoldl&quot;&gt;Generalizing
generic fold&lt;/a&gt;, I introduced the &lt;code&gt;gtraverse&lt;/code&gt; function as an
alternative to &lt;code&gt;gfoldl&lt;/code&gt; for generic programming.&lt;/p&gt;
&lt;p&gt;To remind the important points:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;gtraverse&lt;/code&gt; allows more instances to be written, being
more flexible about which elements can be treated as being on the same
level;&lt;/li&gt;
&lt;li&gt;on the other hand, everything that is possible to do with
&lt;code&gt;gfoldl&lt;/code&gt; seems to be possible to do with
&lt;code&gt;gtraverse&lt;/code&gt;, too.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;It turns out that my intuition was wrong. There is a beautiful
correspondence between &lt;code&gt;gfoldl&lt;/code&gt; and &lt;code&gt;gtraverse&lt;/code&gt;
which shows that they are, in fact, equivalent in power. Read on to find
out why, and what this means for practical generic programming.&lt;/p&gt;
&lt;h2 id=&quot;gtraverse-through-gfoldl&quot;&gt;gtraverse through gfoldl&lt;/h2&gt;
&lt;p&gt;As a quick warm-up, let’s implement &lt;code&gt;gtraverse&lt;/code&gt; through
&lt;code&gt;gfoldl&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;For simplicity, let’s assume that &lt;code&gt;gfoldl&lt;/code&gt; and
&lt;code&gt;gtraverse&lt;/code&gt; are both methods of the same class,
&lt;code&gt;Data&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb1&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb1-1&quot;&gt;&lt;a href=&quot;#cb1-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;{-# LANGUAGE RankNTypes, GADTs, NoMonoLocalBinds #-}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-2&quot;&gt;&lt;a href=&quot;#cb1-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-3&quot;&gt;&lt;a href=&quot;#cb1-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Data&lt;/span&gt; a &lt;span class=&quot;kw&quot;&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-4&quot;&gt;&lt;a href=&quot;#cb1-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  gfoldl&lt;/span&gt;
&lt;span id=&quot;cb1-5&quot;&gt;&lt;a href=&quot;#cb1-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;    ::&lt;/span&gt; (&lt;span class=&quot;kw&quot;&gt;forall&lt;/span&gt; d b&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Data&lt;/span&gt; d &lt;span class=&quot;ot&quot;&gt;=&amp;gt;&lt;/span&gt; c (d &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; b) &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; d &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; c b)&lt;/span&gt;
&lt;span id=&quot;cb1-6&quot;&gt;&lt;a href=&quot;#cb1-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; (&lt;span class=&quot;kw&quot;&gt;forall&lt;/span&gt; g&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt; g &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; c g)&lt;/span&gt;
&lt;span id=&quot;cb1-7&quot;&gt;&lt;a href=&quot;#cb1-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; a &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; c a&lt;/span&gt;
&lt;span id=&quot;cb1-8&quot;&gt;&lt;a href=&quot;#cb1-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-9&quot;&gt;&lt;a href=&quot;#cb1-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  gtraverse&lt;/span&gt;
&lt;span id=&quot;cb1-10&quot;&gt;&lt;a href=&quot;#cb1-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;    ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Applicative&lt;/span&gt; w&lt;/span&gt;
&lt;span id=&quot;cb1-11&quot;&gt;&lt;a href=&quot;#cb1-11&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;ot&quot;&gt;=&amp;gt;&lt;/span&gt; (&lt;span class=&quot;kw&quot;&gt;forall&lt;/span&gt; d &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Data&lt;/span&gt; d &lt;span class=&quot;ot&quot;&gt;=&amp;gt;&lt;/span&gt; d &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; w d)&lt;/span&gt;
&lt;span id=&quot;cb1-12&quot;&gt;&lt;a href=&quot;#cb1-12&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; a &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; w a&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Then&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb2&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb2-1&quot;&gt;&lt;a href=&quot;#cb2-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;gtraverse f &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; gfoldl g &lt;span class=&quot;fu&quot;&gt;pure&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-2&quot;&gt;&lt;a href=&quot;#cb2-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-3&quot;&gt;&lt;a href=&quot;#cb2-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    g acc x &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; acc &lt;span class=&quot;op&quot;&gt;&amp;lt;*&amp;gt;&lt;/span&gt; f x&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;In plain English, when folding, we inject each element into
&lt;code&gt;c&lt;/code&gt; using the supplied function &lt;code&gt;f&lt;/code&gt;, and then
combine it with the accumulator using &lt;code&gt;&amp;lt;*&amp;gt;&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&quot;gfoldl-through-gtraverse&quot;&gt;gfoldl through gtraverse&lt;/h2&gt;
&lt;p&gt;It turns out that &lt;code&gt;gfoldl&lt;/code&gt; can also be interpreted as an
applicative traversal for a particular functor — namely, the &lt;em&gt;free
applicative functor&lt;/em&gt;. We’ll use the one from the &lt;a
href=&quot;http://hackage.haskell.org/packages/archive/free/3.2/doc/html/Control-Applicative-Free.html&quot;&gt;free&lt;/a&gt;
package for now.&lt;/p&gt;
&lt;p&gt;If we run &lt;code&gt;gtraverse&lt;/code&gt; with &lt;code&gt;liftAp Identity&lt;/code&gt;
(where &lt;code&gt;Identity&lt;/code&gt; wraps its element into a trivial
applicative functor), we’ll get a &lt;em&gt;list&lt;/em&gt; rather than a
&lt;em&gt;tree&lt;/em&gt;, which can be easily folded in a &lt;code&gt;gfoldl&lt;/code&gt;-like
fashion.&lt;/p&gt;
&lt;p&gt;One minor issue is that &lt;code&gt;Identity&lt;/code&gt; has to capture the
&lt;code&gt;Data&lt;/code&gt; dictionary of the elements. We can easily achieve that
using a GADT&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb3&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb3-1&quot;&gt;&lt;a href=&quot;#cb3-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;I&lt;/span&gt; a &lt;span class=&quot;kw&quot;&gt;where&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;I&lt;/span&gt;&lt;span class=&quot;ot&quot;&gt; ::&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;forall&lt;/span&gt; a &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Data&lt;/span&gt; a &lt;span class=&quot;ot&quot;&gt;=&amp;gt;&lt;/span&gt; a &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;I&lt;/span&gt; a&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now, &lt;code&gt;gtraverse (liftAp . I)&lt;/code&gt; has type
&lt;code&gt;Data a =&amp;gt; a -&amp;gt; Ap I a&lt;/code&gt;. It transforms any value for
which &lt;code&gt;gtraverse&lt;/code&gt; is defined to a (heterogeneous) list
&lt;code&gt;Ap I a&lt;/code&gt;, which contains all immediate children of that
value, together with their &lt;code&gt;Data&lt;/code&gt; dictionaries.&lt;/p&gt;
&lt;p&gt;The next step is to fold that list:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb4&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb4-1&quot;&gt;&lt;a href=&quot;#cb4-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;foldAp&lt;/span&gt;
&lt;span id=&quot;cb4-2&quot;&gt;&lt;a href=&quot;#cb4-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;  ::&lt;/span&gt; (&lt;span class=&quot;kw&quot;&gt;forall&lt;/span&gt; d b&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Data&lt;/span&gt; d &lt;span class=&quot;ot&quot;&gt;=&amp;gt;&lt;/span&gt; c (d &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; b) &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; d &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; c b)&lt;/span&gt;
&lt;span id=&quot;cb4-3&quot;&gt;&lt;a href=&quot;#cb4-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; (&lt;span class=&quot;kw&quot;&gt;forall&lt;/span&gt; g&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt; g &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; c g)&lt;/span&gt;
&lt;span id=&quot;cb4-4&quot;&gt;&lt;a href=&quot;#cb4-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Ap&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;I&lt;/span&gt; a &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; c a&lt;/span&gt;
&lt;span id=&quot;cb4-5&quot;&gt;&lt;a href=&quot;#cb4-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;foldAp f z (&lt;span class=&quot;dt&quot;&gt;Pure&lt;/span&gt; x) &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; z x&lt;/span&gt;
&lt;span id=&quot;cb4-6&quot;&gt;&lt;a href=&quot;#cb4-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;foldAp f z (&lt;span class=&quot;dt&quot;&gt;Ap&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;I&lt;/span&gt; x) k) &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; (foldAp f z k) &lt;span class=&quot;ot&quot;&gt;`f`&lt;/span&gt; x&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;foldAp&lt;/code&gt; takes the same two functional arguments as
&lt;code&gt;gfoldl&lt;/code&gt;. But instead of working on the original value, it
works on the flattened &lt;code&gt;Ap&lt;/code&gt;-list.&lt;/p&gt;
&lt;p&gt;After gluing the two steps together, we get&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb5&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb5-1&quot;&gt;&lt;a href=&quot;#cb5-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;gfoldl f z &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; foldAp f z &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt; gtraverse (liftAp &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;I&lt;/span&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Nice!&lt;/p&gt;
&lt;h2 id=&quot;consequences&quot;&gt;Consequences&lt;/h2&gt;
&lt;p&gt;So, what does this mean? Do you not need &lt;code&gt;gtraverse&lt;/code&gt; since
&lt;code&gt;gfoldl&lt;/code&gt; can do all the same things?&lt;/p&gt;
&lt;p&gt;No!&lt;/p&gt;
&lt;p&gt;It is much easier to write instances for your data types using
&lt;code&gt;gtraverse&lt;/code&gt;, especially when you want to present an
alternative view on the type from what is directly implied by its
definition. (If you doubt it, you can still try to encode the uniform
&lt;code&gt;Data&lt;/code&gt; instance for lists and compare it with the &lt;a
href=&quot;/articles/2013-03-11-generalizing-gfoldl&quot;&gt;&lt;code&gt;gtraverse&lt;/code&gt;-based&lt;/a&gt;
one.)&lt;/p&gt;
&lt;p&gt;On the other hand, it is nice to know that we don’t really lose any
power by adopting &lt;code&gt;gtraverse&lt;/code&gt; instead of
&lt;code&gt;gfoldl&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;You can try it out right now: I’ve just uploaded the first version of
&lt;a
href=&quot;https://github.com/UnkindPartition/traverse-with-class&quot;&gt;traverse-with-class&lt;/a&gt;
on &lt;a
href=&quot;http://hackage.haskell.org/package/traverse-with-class&quot;&gt;hackage&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;remaining-issues&quot;&gt;Remaining issues&lt;/h2&gt;
&lt;p&gt;There are a couple of issues in our &lt;code&gt;gfoldl&lt;/code&gt;
implementation above&lt;a href=&quot;#fn1&quot; class=&quot;footnote-ref&quot; id=&quot;fnref1&quot;
role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;1&lt;/sup&gt;&lt;/a&gt;:&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;Because of the free applicative functor usage, it has the same
quadratic complexity problems as &lt;a
href=&quot;http://www.iai.uni-bonn.de/~jv/mpc08.pdf&quot;&gt;free monads&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Because of &lt;a
href=&quot;/articles/2013-03-31-flavours-of-free-applicative-functors&quot;&gt;the
way this free applicative works&lt;/a&gt;, our &lt;code&gt;gfoldl&lt;/code&gt; is really a
&lt;code&gt;gfoldr&lt;/code&gt;: it traverses the elements in the reverse
order.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;I’ll talk more about these in subsequent articles.&lt;/p&gt;
&lt;section id=&quot;footnotes&quot; class=&quot;footnotes footnotes-end-of-document&quot;
role=&quot;doc-endnotes&quot;&gt;
&lt;hr /&gt;
&lt;ol&gt;
&lt;li id=&quot;fn1&quot;&gt;&lt;p&gt;to make it clear, there are no such issues in the
library, because it doesn’t provide a &lt;code&gt;gfoldl&lt;/code&gt; function. It
provides unrelated functions &lt;code&gt;gfoldl&apos;&lt;/code&gt; and
&lt;code&gt;gfoldr&lt;/code&gt; with different types.&lt;a href=&quot;#fnref1&quot;
class=&quot;footnote-back&quot; role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</description>
                        <pubDate>Fri, 29 Mar 2013 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2013-03-29-gtraverse-vs-gfoldl</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2013-03-29-gtraverse-vs-gfoldl.html</guid>
                </item>
        
                <item>
                        <title>Ergative verbs in programming</title>
                        <description>&lt;p&gt;For a long time I felt uncomfortable with phrases like «my program
doesn’t compile».&lt;/p&gt;
&lt;p&gt;Of course it doesn’t compile, stupid! &lt;em&gt;It’s not a
compiler!&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;I understood that this phrase was supposed to mean «The compiler
fails to compile my program». But nevertheless it seemed like a wrong
usage of the verb «compile».&lt;/p&gt;
&lt;p&gt;Well, today I learned (thanks to &lt;a
href=&quot;http://english.stackexchange.com/a/107292/2978&quot;&gt;Edwin
Ashworth&lt;/a&gt;) that this is a common phenomenon in English. It’s called
&lt;a href=&quot;http://en.wikipedia.org/wiki/Ergative_verb&quot;&gt;ergative usage&lt;/a&gt;.
There is a &lt;a
href=&quot;http://en.wiktionary.org/w/index.php?title=Category:English_ergative_verbs&quot;&gt;long
list of ergative verbs&lt;/a&gt; on Wiktionary, and «&lt;a
href=&quot;http://en.wiktionary.org/wiki/compile#English&quot;&gt;compile&lt;/a&gt;» is
there!&lt;/p&gt;
&lt;p&gt;This is a list of programming-related verbs that I’ve seen being used
ergatively:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;parse&lt;/li&gt;
&lt;li&gt;type-check&lt;/li&gt;
&lt;li&gt;compile&lt;/li&gt;
&lt;li&gt;build&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You can notice that they all follow the same pattern — something that
one program (usually a compiler) does to another program. I’d be curious
to find computing-related ergative verbs that do not fall into this
pattern.&lt;/p&gt;
</description>
                        <pubDate>Thu, 14 Mar 2013 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2013-03-14-ergative-verbs-in-programming</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2013-03-14-ergative-verbs-in-programming.html</guid>
                </item>
        
                <item>
                        <title>Generalizing generic fold</title>
                        <description>&lt;h2 id=&quot;uniform-folding&quot;&gt;Uniform folding&lt;/h2&gt;
&lt;p&gt;Suppose we’ve created a new container data structure in Haskell, such
as &lt;code&gt;Data.Sequence.Seq&lt;/code&gt;. We now want to write a
&lt;code&gt;Data&lt;/code&gt; instance for it, to allow generic queries and
transforms inside our container.&lt;/p&gt;
&lt;p&gt;Let’s recall &lt;code&gt;gfoldl&lt;/code&gt; definition for lists:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb1&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb1-1&quot;&gt;&lt;a href=&quot;#cb1-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;gfoldl f z [] &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; z []&lt;/span&gt;
&lt;span id=&quot;cb1-2&quot;&gt;&lt;a href=&quot;#cb1-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;gfoldl f z (x&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt;xs) &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; z (&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt;) &lt;span class=&quot;ot&quot;&gt;`f`&lt;/span&gt; x &lt;span class=&quot;ot&quot;&gt;`f`&lt;/span&gt; xs&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;We can define &lt;code&gt;gfoldl&lt;/code&gt; similarly for sequences (in fact,
this is the precise definition from &lt;code&gt;Data.Sequence&lt;/code&gt;):&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb2&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb2-1&quot;&gt;&lt;a href=&quot;#cb2-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;gfoldl f z s &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;case&lt;/span&gt; viewl s &lt;span class=&quot;kw&quot;&gt;of&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-2&quot;&gt;&lt;a href=&quot;#cb2-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;dt&quot;&gt;EmptyL&lt;/span&gt;  &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; z empty&lt;/span&gt;
&lt;span id=&quot;cb2-3&quot;&gt;&lt;a href=&quot;#cb2-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  x &lt;span class=&quot;op&quot;&gt;:&amp;lt;&lt;/span&gt; xs &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; z (&lt;span class=&quot;op&quot;&gt;&amp;lt;|&lt;/span&gt;) &lt;span class=&quot;ot&quot;&gt;`f`&lt;/span&gt; x &lt;span class=&quot;ot&quot;&gt;`f`&lt;/span&gt; xs&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;There are, however, downsides to this definition:&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;&lt;p&gt;Generic map over our container would be less efficient than
hand-written map, even if we ignore the costs associated with run-time
type casts.&lt;/p&gt;
&lt;p&gt;Indeed, in the generic definition we do not take advantage of the
fact that we already have a proper container structure for our elements.
Instead, we construct the structure from scratch, adding elements one by
one. This overhead may be small for &lt;code&gt;Seq&lt;/code&gt;, whose cons is
O(1). But in case of an array-based structure, such as
&lt;code&gt;Vector&lt;/code&gt;, we’re out of luck.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If we only care about the &lt;em&gt;closed recursion&lt;/em&gt; combinators,
such as &lt;code&gt;everywhere&lt;/code&gt;, we wouldn’t know the difference. But
when &lt;em&gt;open recursion&lt;/em&gt; is needed (e.g. &lt;code&gt;gmapT&lt;/code&gt;), the
semantics is not the one we’d expect. The intuition is that
&lt;code&gt;gmapT&lt;/code&gt; maps over the immediate «subterms» of an expression.
One might expect that the subterms of &lt;code&gt;Seq a&lt;/code&gt; are all of its
elements (of type &lt;code&gt;a&lt;/code&gt;). But no, we’re forced into this
recursive list mindset, where the immediate subterms of a sequence are
its head and tail.&lt;/p&gt;
&lt;p&gt;(To be fair, it does make sense if we imagine data structures really
being inductively-defined terms. But it is a very limited
worldview.)&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Can we define &lt;code&gt;gfoldl&lt;/code&gt; in the uniform fashion, folding
over all the elements at once? Try this yourself to understand better
why it’s not easy.&lt;/p&gt;
&lt;p&gt;I haven’t actually done it, but I think it’s achievable using some
amount of type class hackery. Anyway, having to come up with such hacks
defeats the point of an easy-to-use generic programming library.&lt;/p&gt;
&lt;p&gt;In essence, the limitation of &lt;code&gt;gfoldl&lt;/code&gt; is that it forces
us to know the number of elements in advance. We cannot (easily)
construct the result of the fold by recursive computation.&lt;/p&gt;
&lt;h2 id=&quot;generic-traversals&quot;&gt;Generic traversals&lt;/h2&gt;
&lt;p&gt;In order to resolve the problem stated above, we need to
&lt;em&gt;restrict&lt;/em&gt; the type of &lt;code&gt;gfoldl&lt;/code&gt;&lt;a href=&quot;#fn1&quot;
class=&quot;footnote-ref&quot; id=&quot;fnref1&quot;
role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;1&lt;/sup&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Recall its type:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb3&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb3-1&quot;&gt;&lt;a href=&quot;#cb3-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;gfoldl ::&lt;/span&gt; (&lt;span class=&quot;kw&quot;&gt;forall&lt;/span&gt; d b&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Data&lt;/span&gt; d &lt;span class=&quot;ot&quot;&gt;=&amp;gt;&lt;/span&gt; c (d &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; b) &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; d &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; c b)&lt;/span&gt;
&lt;span id=&quot;cb3-2&quot;&gt;&lt;a href=&quot;#cb3-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;       &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; (&lt;span class=&quot;kw&quot;&gt;forall&lt;/span&gt; g&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt; g &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; c g)&lt;/span&gt;
&lt;span id=&quot;cb3-3&quot;&gt;&lt;a href=&quot;#cb3-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;       &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; a &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; c a&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;What might the first functional argument of &lt;code&gt;gfoldl&lt;/code&gt; do?
It &lt;em&gt;probably&lt;/em&gt; transforms &lt;code&gt;d&lt;/code&gt; to something like
&lt;code&gt;c d&lt;/code&gt; by using its &lt;code&gt;Data&lt;/code&gt; instance, and then
combines &lt;code&gt;c (d -&amp;gt; b)&lt;/code&gt; with &lt;code&gt;c d&lt;/code&gt; to obtain
&lt;code&gt;c b&lt;/code&gt;. This is not a sure thing, of course: the caller of
&lt;code&gt;gfoldl&lt;/code&gt; knows what &lt;code&gt;c&lt;/code&gt; exactly is, so it might
combine them in unexpected ways. Let us proceed with this assumption,
however; as I said above, we need to restrict the caller in order to
give more power to the callee.&lt;/p&gt;
&lt;p&gt;So, if our guess is correct, we can separate the two activities into
two different functions:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb4&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb4-1&quot;&gt;&lt;a href=&quot;#cb4-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;gfoldl ::&lt;/span&gt; (&lt;span class=&quot;kw&quot;&gt;forall&lt;/span&gt; d&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Data&lt;/span&gt; d &lt;span class=&quot;ot&quot;&gt;=&amp;gt;&lt;/span&gt; d &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; c d)&lt;/span&gt;
&lt;span id=&quot;cb4-2&quot;&gt;&lt;a href=&quot;#cb4-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;       &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; (&lt;span class=&quot;kw&quot;&gt;forall&lt;/span&gt; d b&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt; c (d &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; b) &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; c d &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; c b)&lt;/span&gt;
&lt;span id=&quot;cb4-3&quot;&gt;&lt;a href=&quot;#cb4-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;       &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; (&lt;span class=&quot;kw&quot;&gt;forall&lt;/span&gt; g&lt;span class=&quot;op&quot;&gt;.&lt;/span&gt; g &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; c g)&lt;/span&gt;
&lt;span id=&quot;cb4-4&quot;&gt;&lt;a href=&quot;#cb4-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;       &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; a &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; c a&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The whole thing now suddenly becomes very familiar: &lt;code&gt;c&lt;/code&gt; is
an applicative functor! The second and third arguments are
&lt;code&gt;&amp;lt;*&amp;gt;&lt;/code&gt; and &lt;code&gt;pure&lt;/code&gt;, respectively. And the
applicative laws had better hold — there are now many ways to express
the same thing, and we don’t expect there to be a difference.&lt;/p&gt;
&lt;p&gt;Using the &lt;code&gt;Applicative&lt;/code&gt; class, we can rewrite the type
as&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb5&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb5-1&quot;&gt;&lt;a href=&quot;#cb5-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;gtraverse ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Applicative&lt;/span&gt; c &lt;span class=&quot;ot&quot;&gt;=&amp;gt;&lt;/span&gt; (&lt;span class=&quot;kw&quot;&gt;forall&lt;/span&gt; d &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;GTraversable&lt;/span&gt; d &lt;span class=&quot;ot&quot;&gt;=&amp;gt;&lt;/span&gt; d &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; c d) &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; a &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; c a&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Note that I took this chance to rename our restricted
&lt;code&gt;gfoldl&lt;/code&gt; to &lt;code&gt;gtraverse&lt;/code&gt; and &lt;code&gt;Data&lt;/code&gt; to
&lt;code&gt;GTraversable&lt;/code&gt;. The reason is that it is a generic version of
&lt;code&gt;traverse&lt;/code&gt; from &lt;code&gt;Data.Traversable&lt;/code&gt;, whose type
is&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb6&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb6-1&quot;&gt;&lt;a href=&quot;#cb6-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;fu&quot;&gt;traverse&lt;/span&gt;&lt;span class=&quot;ot&quot;&gt; ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Applicative&lt;/span&gt; c &lt;span class=&quot;ot&quot;&gt;=&amp;gt;&lt;/span&gt; (a &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; c b) &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; t a &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; c (t b)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Read the type of &lt;code&gt;gtraverse&lt;/code&gt; as «traverse this structure,
applying the supplied function to the immediate subterms; then use the
&lt;code&gt;Applicative&lt;/code&gt; instance to reconstruct the original
structure».&lt;/p&gt;
&lt;p&gt;We can now write the uniform instance for lists (and any other
algebraic data type) without a hassle:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb7&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb7-1&quot;&gt;&lt;a href=&quot;#cb7-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;gtraverse f [] &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;pure&lt;/span&gt; []&lt;/span&gt;
&lt;span id=&quot;cb7-2&quot;&gt;&lt;a href=&quot;#cb7-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;gtraverse f (x&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt;xs) &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; (&lt;span class=&quot;op&quot;&gt;:&lt;/span&gt;) &lt;span class=&quot;op&quot;&gt;&amp;lt;$&amp;gt;&lt;/span&gt; f x &lt;span class=&quot;op&quot;&gt;&amp;lt;*&amp;gt;&lt;/span&gt; gtraverse f xs&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;But how does it restrict the caller of &lt;code&gt;gfoldl&lt;/code&gt;? Not much.
All the usual combinators, such as &lt;code&gt;gmapT&lt;/code&gt;,
&lt;code&gt;gmapQ&lt;/code&gt;, &lt;code&gt;gmapM&lt;/code&gt; etc. are expressible with
&lt;code&gt;gtraverse&lt;/code&gt;. I’d be curious to see an application of
&lt;code&gt;gfoldl&lt;/code&gt; for which &lt;code&gt;gtraverse&lt;/code&gt; is too
restrictive&lt;a href=&quot;#fn2&quot; class=&quot;footnote-ref&quot; id=&quot;fnref2&quot;
role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;2&lt;/sup&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;section id=&quot;footnotes&quot; class=&quot;footnotes footnotes-end-of-document&quot;
role=&quot;doc-endnotes&quot;&gt;
&lt;hr /&gt;
&lt;ol&gt;
&lt;li id=&quot;fn1&quot;&gt;&lt;p&gt;Yes, the article’s title is a lie. Thanks for reading
this far. What we are really &lt;em&gt;generalizing&lt;/em&gt;, by allowing more
instances, is the &lt;code&gt;Data&lt;/code&gt; class.&lt;a href=&quot;#fnref1&quot;
class=&quot;footnote-back&quot; role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li id=&quot;fn2&quot;&gt;&lt;p&gt;See &lt;a
href=&quot;/articles/2013-03-29-gtraverse-vs-gfoldl&quot;&gt;gtraverse vs. gfoldl&lt;/a&gt;
which shows that &lt;code&gt;gtraverse&lt;/code&gt; and &lt;code&gt;gfoldl&lt;/code&gt; are in
fact equivalent in power.&lt;a href=&quot;#fnref2&quot; class=&quot;footnote-back&quot;
role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</description>
                        <pubDate>Mon, 11 Mar 2013 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2013-03-11-generalizing-gfoldl</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2013-03-11-generalizing-gfoldl.html</guid>
                </item>
        
                <item>
                        <title>Open your name resolution</title>
                        <description>&lt;h2 id=&quot;what-is-name-resolution&quot;&gt;What is name resolution?&lt;/h2&gt;
&lt;p&gt;Name resolution is a program analysis which for every name decides
what that name refers to.&lt;/p&gt;
&lt;p&gt;Consider the following Haskell program as an example:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb1&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb1-1&quot;&gt;&lt;a href=&quot;#cb1-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;n ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Integer&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-2&quot;&gt;&lt;a href=&quot;#cb1-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;n &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;let&lt;/span&gt; k &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;10&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;in&lt;/span&gt; k &lt;span class=&quot;op&quot;&gt;*&lt;/span&gt; k&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;There are three names in this program: &lt;code&gt;n&lt;/code&gt;, &lt;code&gt;k&lt;/code&gt;
and &lt;code&gt;Integer&lt;/code&gt;. The result of name resolution in this case
would be:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;n&lt;/code&gt; refers to the global value defined in the program
itself, on lines 1-2;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Integer&lt;/code&gt; refers to the type (implicitly) imported from
&lt;code&gt;Prelude&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;k&lt;/code&gt; on line 2 is a local value defined on the same
line.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This article is concerned with the following question: &lt;strong&gt;how
should the API of a name resolution library be structured&lt;/strong&gt;?&lt;/p&gt;
&lt;h2 id=&quot;annotations&quot;&gt;Annotations&lt;/h2&gt;
&lt;p&gt;The standard approach is a function that transforms a simple AST to
the annotated AST, where every name is annotated with its binding
information (just like we did above).&lt;/p&gt;
&lt;p&gt;(Note that a simple map from names to binding information won’t do:
the same name can refer to different things in different parts of the
program.)&lt;/p&gt;
&lt;p&gt;This is enough for most applications of name resolution, such as type
checking, compilation or static analysis.&lt;/p&gt;
&lt;h3 id=&quot;significance-of-lexical-environment&quot;&gt;Significance of lexical
environment&lt;/h3&gt;
&lt;p&gt;However, simple annotations are not enough for source-to-source
transformations, like the ones performed by &lt;a
href=&quot;http://www.haskell.org/haskellwiki/HaRe&quot;&gt;HaRe&lt;/a&gt; or &lt;a
href=&quot;http://www.youtube.com/watch?v=Ae-6uIMQPmU&quot;&gt;HasFix&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Such transformations typically require access to the whole symbol
table to avoid variable capture. As an example, imagine that in the new
version of some module &lt;code&gt;Mod&lt;/code&gt; &lt;code&gt;foo&lt;/code&gt; has been
renamed to &lt;code&gt;bar&lt;/code&gt;, and we want to adapt our own code to use
this new version. And our code looks like this:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb2&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb2-1&quot;&gt;&lt;a href=&quot;#cb2-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;baz x &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;let&lt;/span&gt; bar &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; x &lt;span class=&quot;op&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;in&lt;/span&gt; foo bar&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Name resolution tells us that &lt;code&gt;foo&lt;/code&gt; on that line indeed
comes from &lt;code&gt;Mod&lt;/code&gt; and should be renamed. But if we blindly
apply the renaming, we’ll get&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb3&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb3-1&quot;&gt;&lt;a href=&quot;#cb3-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;baz x &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;let&lt;/span&gt; bar &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; x &lt;span class=&quot;op&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;in&lt;/span&gt; bar bar&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;where &lt;code&gt;bar&lt;/code&gt; no longer refers to the global value imported
from &lt;code&gt;Mod&lt;/code&gt; — it has been captured by &lt;code
class=&quot;sourceCode haskell&quot;&gt;&lt;span class=&quot;kw&quot;&gt;let&lt;/span&gt;&lt;/code&gt;!&lt;/p&gt;
&lt;p&gt;The solution is simple: rename &lt;code&gt;foo&lt;/code&gt; to qualified name
&lt;code&gt;Mod.bar&lt;/code&gt; whenever simple &lt;code&gt;bar&lt;/code&gt; is already defined
in the enclosing lexical scope. It requires us, however, to know the
lexical environment at every point.&lt;/p&gt;
&lt;h3 id=&quot;annotating-with-symbol-tables&quot;&gt;Annotating with symbol
tables&lt;/h3&gt;
&lt;p&gt;Why not store the whole symbol table at every point in the AST? This
could work. In a lazy language this is not even as bad, time- and
space-wise, as it might seem.&lt;/p&gt;
&lt;p&gt;It is cumbersome, however. Every time we replace a subtree, we need
manually to re-run name resolution on the new subtree (or even on the
whole tree, if there’s any possibility that other annotations may become
invalid as a result of the replacement).&lt;/p&gt;
&lt;h2 id=&quot;open-recursion&quot;&gt;Open recursion&lt;/h2&gt;
&lt;p&gt;In order to maintain the symbol table during the traversal, we can
try to keep track of the local bindings ourselves, only to discover that
it’s not that trivial, and that we’re replicating a large part of the
resolution code.&lt;/p&gt;
&lt;p&gt;The core of the problem is that the name resolution algorithm is one
big-step tree traversal, and we can only observe its final result (or a
trace of its execution in the form of annotations).&lt;/p&gt;
&lt;p&gt;If we could split it up into small-step, one layer at a time,
resolution functions, we could use them in our own traversals and
interleave them with transformations. Another name for this approach is
&lt;em&gt;open recursion&lt;/em&gt;, hence the article’s title.&lt;/p&gt;
&lt;h3 id=&quot;single-sorted-ast&quot;&gt;Single-sorted AST&lt;/h3&gt;
&lt;p&gt;If our AST is a single recursive data type (parameterised by the
annotation type)&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb4&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb4-1&quot;&gt;&lt;a href=&quot;#cb4-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;VarName&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;String&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-2&quot;&gt;&lt;a href=&quot;#cb4-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-3&quot;&gt;&lt;a href=&quot;#cb4-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Exp&lt;/span&gt; a&lt;/span&gt;
&lt;span id=&quot;cb4-4&quot;&gt;&lt;a href=&quot;#cb4-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Var&lt;/span&gt; a &lt;span class=&quot;dt&quot;&gt;VarName&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-5&quot;&gt;&lt;a href=&quot;#cb4-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;op&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;App&lt;/span&gt; a (&lt;span class=&quot;dt&quot;&gt;Exp&lt;/span&gt; a) (&lt;span class=&quot;dt&quot;&gt;Exp&lt;/span&gt; a)&lt;/span&gt;
&lt;span id=&quot;cb4-6&quot;&gt;&lt;a href=&quot;#cb4-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;op&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Lambda&lt;/span&gt; a &lt;span class=&quot;dt&quot;&gt;VarName&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;Exp&lt;/span&gt; a)&lt;/span&gt;
&lt;span id=&quot;cb4-7&quot;&gt;&lt;a href=&quot;#cb4-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-8&quot;&gt;&lt;a href=&quot;#cb4-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;SymbolTable&lt;/span&gt; a &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Map.Map&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;VarName&lt;/span&gt; a&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;then such a small-step resolution function would have type&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb5&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb5-1&quot;&gt;&lt;a href=&quot;#cb5-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;resolve&lt;/span&gt;
&lt;span id=&quot;cb5-2&quot;&gt;&lt;a href=&quot;#cb5-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;  ::&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;SymbolTable&lt;/span&gt; a &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Exp&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Exp&lt;/span&gt;)&lt;/span&gt;
&lt;span id=&quot;cb5-3&quot;&gt;&lt;a href=&quot;#cb5-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt;  &lt;span class=&quot;dt&quot;&gt;SymbolTable&lt;/span&gt; a &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Exp&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Exp&lt;/span&gt; &lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;It takes an expression, the symbol table (or &lt;em&gt;environment&lt;/em&gt;)
that corresponds to the enclosing lexical context of that expression,
and a transformation function. It then applies the transformation to all
immediate children of the expression.&lt;/p&gt;
&lt;p&gt;Note that the transformation function is in turn parameterised by the
symbol table. It is the responsibility of &lt;code&gt;resolve&lt;/code&gt; to update
the symbol table accordingly before using it to transform the
children.&lt;/p&gt;
&lt;p&gt;An implementation of &lt;code&gt;resolve&lt;/code&gt; might look like this&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb6&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb6-1&quot;&gt;&lt;a href=&quot;#cb6-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;resolve f tbl e &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-2&quot;&gt;&lt;a href=&quot;#cb6-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;case&lt;/span&gt; e &lt;span class=&quot;kw&quot;&gt;of&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-3&quot;&gt;&lt;a href=&quot;#cb6-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;dt&quot;&gt;Var&lt;/span&gt; l n &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Var&lt;/span&gt; l n&lt;/span&gt;
&lt;span id=&quot;cb6-4&quot;&gt;&lt;a href=&quot;#cb6-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;dt&quot;&gt;App&lt;/span&gt; l e1 e2 &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;App&lt;/span&gt; l (f tbl e1) (f tbl e2)&lt;/span&gt;
&lt;span id=&quot;cb6-5&quot;&gt;&lt;a href=&quot;#cb6-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;dt&quot;&gt;Lambda&lt;/span&gt; l n body &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Lambda&lt;/span&gt; l n (f (Map.insert n l tbl) body)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now that we have &lt;code&gt;resolve&lt;/code&gt;, it is easy to tie the knot and
write the big-step recursive traversal:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb7&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb7-1&quot;&gt;&lt;a href=&quot;#cb7-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;resolveRec ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Exp&lt;/span&gt; a &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Exp&lt;/span&gt; a&lt;/span&gt;
&lt;span id=&quot;cb7-2&quot;&gt;&lt;a href=&quot;#cb7-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;resolveRec &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; fix resolve Map.empty&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;resolveRec&lt;/code&gt; doesn’t do anything interesting — it’s an
identity function. But we can compose &lt;code&gt;resolve&lt;/code&gt; with an
interesting transformation before “closing” the recursion:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb8&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb8-1&quot;&gt;&lt;a href=&quot;#cb8-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;annotate&lt;/span&gt;
&lt;span id=&quot;cb8-2&quot;&gt;&lt;a href=&quot;#cb8-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;  ::&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;SymbolTable&lt;/span&gt; a &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Exp&lt;/span&gt; a &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Exp&lt;/span&gt; a)&lt;/span&gt;
&lt;span id=&quot;cb8-3&quot;&gt;&lt;a href=&quot;#cb8-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt;  &lt;span class=&quot;dt&quot;&gt;SymbolTable&lt;/span&gt; a &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Exp&lt;/span&gt; a &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Exp&lt;/span&gt; a&lt;/span&gt;
&lt;span id=&quot;cb8-4&quot;&gt;&lt;a href=&quot;#cb8-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;annotate f tbl e &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb8-5&quot;&gt;&lt;a href=&quot;#cb8-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;case&lt;/span&gt; e &lt;span class=&quot;kw&quot;&gt;of&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb8-6&quot;&gt;&lt;a href=&quot;#cb8-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;dt&quot;&gt;Var&lt;/span&gt; _ n &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; f tbl &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Var&lt;/span&gt; (tbl &lt;span class=&quot;op&quot;&gt;Map.!&lt;/span&gt; n) n&lt;/span&gt;
&lt;span id=&quot;cb8-7&quot;&gt;&lt;a href=&quot;#cb8-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    _ &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; f tbl e&lt;/span&gt;
&lt;span id=&quot;cb8-8&quot;&gt;&lt;a href=&quot;#cb8-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb8-9&quot;&gt;&lt;a href=&quot;#cb8-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;annotateRec ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Exp&lt;/span&gt; a &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Exp&lt;/span&gt; a&lt;/span&gt;
&lt;span id=&quot;cb8-10&quot;&gt;&lt;a href=&quot;#cb8-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;annotateRec &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; fix (resolve &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt; annotate) Map.empty&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Let’s try it out:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;*Main&amp;gt; annotateRec $ Lambda 1 &amp;quot;x&amp;quot; $ App 2 (Var 3 &amp;quot;x&amp;quot;) (Var 4 &amp;quot;x&amp;quot;)
Lambda 1 &amp;quot;x&amp;quot; (App 2 (Var 1 &amp;quot;x&amp;quot;) (Var 1 &amp;quot;x&amp;quot;))&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Hence, the annotation interface to a name resolution library is easy
to implement given the open recursion interface. But the open recursion
interface is much more powerful, allowing the transformation function to
depend on the lexical environment in non-trivial ways.&lt;/p&gt;
&lt;h3 id=&quot;multi-sorted-ast&quot;&gt;Multi-sorted AST&lt;/h3&gt;
&lt;p&gt;What if our AST is represented by a multitude of mutually recursive
data types, just like in &lt;a
href=&quot;http://hackage.haskell.org/packages/archive/haskell-src-exts/1.13.5/doc/html/Language-Haskell-Exts-Annotated-Syntax.html&quot;&gt;haskell-src-exts&lt;/a&gt;?
Generic programming may help here — specifically, the “Scrap your
boilerplate” approach.&lt;/p&gt;
&lt;p&gt;A stock library, such as syb-with-class, might go a long way, but
let’s roll out our own. It will be simpler this way, but also more
flexible (for example, it’s possible to modify this presentation to
allow the traversal to change the annotation type).&lt;/p&gt;
&lt;p&gt;How does the type of &lt;code&gt;resolve&lt;/code&gt; change? It now has to work
for any AST node type, rather than just for &lt;code
class=&quot;sourceCode haskell&quot;&gt;&lt;span class=&quot;dt&quot;&gt;Exp&lt;/span&gt;&lt;/code&gt;, i.e. be
polymorphic. Furthermore, the functional argument to
&lt;code&gt;resolve&lt;/code&gt;, which used to have type &lt;code
class=&quot;sourceCode haskell&quot;&gt;&lt;span class=&quot;dt&quot;&gt;SymbolTable&lt;/span&gt; a &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Exp&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Exp&lt;/span&gt;&lt;/code&gt;,
also has to be polymorphic, because the types of node’s children may be
different (and may differ from the node’s type itself).&lt;/p&gt;
&lt;p&gt;To encode this polymorphism, one can use either a type class or a
GADT sum type (see &lt;a
href=&quot;http://stackoverflow.com/q/15160470/110081&quot;&gt;this StackOverflow
entry&lt;/a&gt; for comparison of these approaches).&lt;/p&gt;
&lt;p&gt;Although we are dealing with a finite, closed universe (consisting of
haskell-src-exts node types) in this case, I prefer the class-based
approach because it’s more practical — it doesn’t force us to define a
giant GADT.&lt;/p&gt;
&lt;p&gt;Thus, &lt;code&gt;resolve&lt;/code&gt; now becomes a class method:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb10&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb10-1&quot;&gt;&lt;a href=&quot;#cb10-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Typeable&lt;/span&gt; a &lt;span class=&quot;ot&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Resolvable&lt;/span&gt; a &lt;span class=&quot;kw&quot;&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb10-2&quot;&gt;&lt;a href=&quot;#cb10-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  resolve&lt;/span&gt;
&lt;span id=&quot;cb10-3&quot;&gt;&lt;a href=&quot;#cb10-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;    ::&lt;/span&gt; (&lt;span class=&quot;kw&quot;&gt;forall&lt;/span&gt; b &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Resolvable&lt;/span&gt; b &lt;span class=&quot;ot&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;SymbolTable&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; b &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; b)&lt;/span&gt;
&lt;span id=&quot;cb10-4&quot;&gt;&lt;a href=&quot;#cb10-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt;                             &lt;span class=&quot;dt&quot;&gt;SymbolTable&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; a &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; a&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The &lt;code&gt;Typeable&lt;/code&gt; superclass constraint is needed here so
that we can write type-specific cases (such as &lt;code
class=&quot;sourceCode haskell&quot;&gt;&lt;span class=&quot;kw&quot;&gt;case&lt;/span&gt;&lt;/code&gt; for &lt;code
class=&quot;sourceCode haskell&quot;&gt;&lt;span class=&quot;dt&quot;&gt;Var&lt;/span&gt;&lt;/code&gt; in the
&lt;code&gt;annotate&lt;/code&gt; function).&lt;/p&gt;
&lt;p&gt;Otherwise, implementing and using this approach for a multi-sorted
AST is quite similar to the single-sorted case.&lt;/p&gt;
&lt;h2 id=&quot;conclusions&quot;&gt;Conclusions&lt;/h2&gt;
&lt;p&gt;The article argues that the open recursion approach to name
resolution offers more power to the user and shows how to implement
it.&lt;/p&gt;
&lt;p&gt;The presentation here is simplified for the sake of clarity. A full
implementation would allow queries (folds), effectful traversals and
traversal that can change the annotation type.&lt;/p&gt;
&lt;p&gt;For Haskell (and haskell-src-exts AST), I’ve just started
implementing this idea in &lt;a
href=&quot;https://github.com/UnkindPartition/haskell-names&quot;&gt;haskell-names&lt;/a&gt;.&lt;/p&gt;
</description>
                        <pubDate>Mon, 04 Mar 2013 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2013-03-04-open-name-resolution</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2013-03-04-open-name-resolution.html</guid>
                </item>
        
                <item>
                        <title>Announcing SmallCheck 1.0</title>
                        <description>&lt;p&gt;I am glad to announce a new major release of SmallCheck (&lt;a
href=&quot;http://hackage.haskell.org/package/smallcheck-1.0&quot;&gt;hackage&lt;/a&gt;).&lt;/p&gt;
&lt;h2 id=&quot;what-is-smallcheck&quot;&gt;What is SmallCheck?&lt;/h2&gt;
&lt;p&gt;&lt;a
href=&quot;https://github.com/UnkindPartition/smallcheck&quot;&gt;SmallCheck&lt;/a&gt; is a
property-based testing library for Haskell.&lt;/p&gt;
&lt;p&gt;If you are familiar with QuickCheck, you can think of SmallCheck as a
&lt;a
href=&quot;https://github.com/UnkindPartition/smallcheck/wiki/Comparison-with-QuickCheck&quot;&gt;better&lt;/a&gt;
QuickCheck. The main way in which it is better is that it is non-random:
whether your tests pass does not depend on the roll of the dice.&lt;/p&gt;
&lt;p&gt;If you are not familiar with QuickCheck, the idea of SmallCheck is to
check certain &lt;em&gt;properties&lt;/em&gt; of your functions, as opposed to unit
testing, where you just check the expected outcome of some particular
tests.&lt;/p&gt;
&lt;p&gt;For an introduction to property-based testing, check out &lt;a
href=&quot;http://book.realworldhaskell.org/read/testing-and-quality-assurance.html&quot;&gt;Chapter
11&lt;/a&gt; of Real World Haskell. It should be straightforward to translate
all the examples there to SmallCheck.&lt;/p&gt;
&lt;h2 id=&quot;whats-new-in-1.0&quot;&gt;What’s new in 1.0&lt;/h2&gt;
&lt;h3 id=&quot;monadic-properties&quot;&gt;Monadic properties&lt;/h3&gt;
&lt;p&gt;Properties are now parameterised on the monad they work in.&lt;/p&gt;
&lt;p&gt;The two main ways a property can use the monad are:&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;generating test cases monadically&lt;/li&gt;
&lt;li&gt;verifying the condition monadically&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Monadic test cases generation can be used to read test cases from
files. A well-known problem when testing compilers is that it is hard to
enumerate or randomly generate valid programs. So here you go — just put
some examples in the file system, and use them to verify some properties
of your compiler.&lt;/p&gt;
&lt;p&gt;An example of monadic verification is when you want to verify your
code against an external (or otherwise impure) reference
implementation.&lt;/p&gt;
&lt;h3 id=&quot;quantifiers&quot;&gt;Quantifiers&lt;/h3&gt;
&lt;p&gt;The semantics of quantifiers has changed. Previously, all variables
were quantified universally by default, and a quantifier (like
&lt;code&gt;exists&lt;/code&gt;) changed the quantification of the next
variable.&lt;/p&gt;
&lt;p&gt;So, for example, &lt;code&gt;exists $ \x y -&amp;gt; p x y&lt;/code&gt; was
interpreted as &lt;span class=&quot;math inline&quot;&gt;\(\exists x: \forall
y. p\ x\ y\)&lt;/span&gt;, which is probably not what one would expect.&lt;/p&gt;
&lt;p&gt;Now the quantification operators (&lt;code&gt;forAll&lt;/code&gt;,
&lt;code&gt;exists&lt;/code&gt; and &lt;code&gt;existsUnique&lt;/code&gt;) set the
quantification context for all subsequent variables, so the above
property means &lt;span class=&quot;math inline&quot;&gt;\(\exists x, y: p\ x\
y\)&lt;/span&gt;.&lt;/p&gt;
&lt;h4 id=&quot;uniqueness-quantification&quot;&gt;Uniqueness quantification&lt;/h4&gt;
&lt;p&gt;There’s an interesting effect related to the uniqueness quantifier
&lt;code&gt;existsUnique&lt;/code&gt; (which was previously called
&lt;code&gt;exists1&lt;/code&gt;).&lt;/p&gt;
&lt;p&gt;There are two ways to interpret
&lt;code&gt;existsUnique $ \x y -&amp;gt; p x y&lt;/code&gt;, “curried” and
“uncurried”:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span class=&quot;math inline&quot;&gt;\(\exists ! x: \exists ! y: p\ x\
y\)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span class=&quot;math inline&quot;&gt;\(\exists ! (x,y): p\ x\ y\)&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;These two actually have different meaning. Suppose that &lt;span
class=&quot;math inline&quot;&gt;\(p\ x\ y=(|x|=|y|)\)&lt;/span&gt;, where &lt;span
class=&quot;math inline&quot;&gt;\(|x|\)&lt;/span&gt; denotes the absolute value of an
integer &lt;span class=&quot;math inline&quot;&gt;\(x\)&lt;/span&gt;. Then the first property
above is true, and the second is false (be sure to check this
yourself).&lt;/p&gt;
&lt;p&gt;When mathematicians write &lt;span class=&quot;math inline&quot;&gt;\(\exists !
x,y:p\ x\ y\)&lt;/span&gt;, they really mean the second interpretation, so
this is what SmallCheck implements (although the first interpretation
would be much easier to implement).&lt;/p&gt;
&lt;h3 id=&quot;higher-order-properties&quot;&gt;Higher-order properties&lt;/h3&gt;
&lt;p&gt;Both SmallCheck and QuickCheck have a &lt;code&gt;==&amp;gt;&lt;/code&gt; operator,
which tests an implication. The left argument of &lt;code&gt;==&amp;gt;&lt;/code&gt; has
type &lt;code&gt;Bool&lt;/code&gt;, and it’s usually a statement that the generated
arguments satisfy some side condition (e.g. generated programs are
valid).&lt;/p&gt;
&lt;p&gt;In this new version of SmallCheck, the left argument of
&lt;code&gt;==&amp;gt;&lt;/code&gt; can be an arbitrary property, with its own
quantifiers etc. Here’s how we could test an &lt;code&gt;isPrime&lt;/code&gt;
function:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb1&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb1-1&quot;&gt;&lt;a href=&quot;#cb1-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Test.SmallCheck&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-2&quot;&gt;&lt;a href=&quot;#cb1-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Test.SmallCheck.Series&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-3&quot;&gt;&lt;a href=&quot;#cb1-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-4&quot;&gt;&lt;a href=&quot;#cb1-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;isPrime ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Integer&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Bool&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-5&quot;&gt;&lt;a href=&quot;#cb1-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;isPrime _ &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;True&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-6&quot;&gt;&lt;a href=&quot;#cb1-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-7&quot;&gt;&lt;a href=&quot;#cb1-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;main &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;/span&gt;
&lt;span id=&quot;cb1-8&quot;&gt;&lt;a href=&quot;#cb1-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  smallCheck &lt;span class=&quot;dv&quot;&gt;5&lt;/span&gt; &lt;span class=&quot;co&quot;&gt;{- 5 is the testing depth -}&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-9&quot;&gt;&lt;a href=&quot;#cb1-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    \(&lt;span class=&quot;dt&quot;&gt;Positive&lt;/span&gt; n) &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-10&quot;&gt;&lt;a href=&quot;#cb1-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;      (exists &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; \(&lt;span class=&quot;dt&quot;&gt;Positive&lt;/span&gt; d) &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; d &lt;span class=&quot;op&quot;&gt;/=&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; d &lt;span class=&quot;op&quot;&gt;/=&lt;/span&gt; n &lt;span class=&quot;op&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; n &lt;span class=&quot;ot&quot;&gt;`mod`&lt;/span&gt; d &lt;span class=&quot;op&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;0&lt;/span&gt;) &lt;span class=&quot;op&quot;&gt;==&amp;gt;&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;not&lt;/span&gt; (isPrime n)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Unsurprisingly, the result will be&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Failed test no. 4.
there exists 4 such that
  condition is false&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;ordered-testing&quot;&gt;Ordered testing&lt;/h3&gt;
&lt;p&gt;SmallCheck has just got more efficient and less annoying!&lt;/p&gt;
&lt;p&gt;Previously, if you wanted to get the &lt;em&gt;minimal&lt;/em&gt; counterexample,
you used the function &lt;code&gt;smallCheck&lt;/code&gt; which tested the property
first with depth 0, then with depth 1 and so on — up to the limit that
you told it.&lt;/p&gt;
&lt;p&gt;The reason was that the &lt;code&gt;Serial&lt;/code&gt; instance of
e.g. &lt;code&gt;Integer&lt;/code&gt; generated the following integers for depth
&lt;code&gt;3&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[-3,-2,-1,0,1,2,3]&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;They are tried in exactly this order, and, if all of them were
counterexamples, the user would be presented with &lt;code&gt;-3&lt;/code&gt; as the
first one.&lt;/p&gt;
&lt;p&gt;Now the instances generate examples in the order of increasing depth,
e.g.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[0,1,-1,2,-2,3,-3]&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;so there’s no need to try multiple depths.&lt;/p&gt;
&lt;h3 id=&quot;better-reporting&quot;&gt;Better reporting&lt;/h3&gt;
&lt;p&gt;The way SmallCheck reports its findings is now greatly improved,
especially in some complex cases.&lt;/p&gt;
&lt;p&gt;For example, consider the following property:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb5&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb5-1&quot;&gt;&lt;a href=&quot;#cb5-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;smallCheck &lt;span class=&quot;dv&quot;&gt;5&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; existsUnique &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; \x &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; (forAll &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; \y &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; x &lt;span class=&quot;op&quot;&gt;*&lt;/span&gt; y &lt;span class=&quot;op&quot;&gt;&amp;gt;=&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;0&lt;/span&gt;) &lt;span class=&quot;op&quot;&gt;==&amp;gt;&lt;/span&gt; (forAll &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; \y &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; x &lt;span class=&quot;op&quot;&gt;*&lt;/span&gt; y &lt;span class=&quot;op&quot;&gt;==&lt;/span&gt; (&lt;span class=&quot;dv&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;ot&quot;&gt; ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Integer&lt;/span&gt;))&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Here’s what SmallCheck 0.6.2 reports (or, to be precise,
&lt;em&gt;would&lt;/em&gt; report if it supported higher-order properties):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Depth 0:
  Completed 1 test(s) without failure.
Depth 1:
  Failed test no. 12. Test values follow.
  non-uniqueness
  -1
  0&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And this is the output of SmallCheck 1.0:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Failed test no. 12.
there are at least two arguments satisfying the property:
  for 0
    condition is true
  for 1
    property is vacuously true because
      there exists -1 such that
        condition is false&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;required-type-annotations&quot;&gt;Required type annotations&lt;/h3&gt;
&lt;p&gt;Because the &lt;code&gt;Testable&lt;/code&gt; class is now multi-parameter
(parameterised on the type and the monad), ambiguous types that involve
this class do not get defaulted. To put it simply, most non-trivial
properties now require some type annotations.&lt;/p&gt;
&lt;p&gt;This turned out to be a very good thing for SmallCheck (which I
couldn’t envision). Defaulting for properties often works in an
unexpected way. For example, here’s what an older SmallCheck would tell
you if you asked it whether all things are the equal:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt; depthCheck 5 $ \x y -&amp;gt; x == y
Depth 5:
  Completed 1 test(s) without failure.&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The result is unexpected, but at least we get some clue from the fact
that there was just one test: the type of the variables got defaulted to
&lt;code&gt;()&lt;/code&gt;!&lt;/p&gt;
&lt;p&gt;Alas, QuickCheck doesn’t give us even this hint:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt; quickCheck $ \x y -&amp;gt; x == y
+++ OK, passed 100 tests.&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Luckily, with the new SmallCheck you actually get a type error:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;interactive&amp;gt;:10:26:
    No instance for (Eq a0) arising from a use of `==&amp;#39;
    The type variable `a0&amp;#39; is ambiguous
    Possible fix: add a type signature that fixes these type variable(s)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And indeed, the problem is easy to fix once you know it’s there:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt; smallCheck 5 $ \x y -&amp;gt; x == (y :: Integer)
Failed test no. 2.
there exist 0 1 such that
  condition is false&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;simpler-interface&quot;&gt;Simpler interface&lt;/h3&gt;
&lt;p&gt;I took this chance to clean the API and make it more orthogonal.&lt;/p&gt;
&lt;p&gt;Previously SmallCheck had functions like&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb12&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb12-1&quot;&gt;&lt;a href=&quot;#cb12-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;forAllElem ::&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;Show&lt;/span&gt; a, &lt;span class=&quot;dt&quot;&gt;Testable&lt;/span&gt; b) &lt;span class=&quot;ot&quot;&gt;=&amp;gt;&lt;/span&gt; [a] &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; (a &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; b) &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Property&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;which did three things at once:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;made the variable universally quantified&lt;/li&gt;
&lt;li&gt;converted the list to a depth-independent series&lt;/li&gt;
&lt;li&gt;quantified the variable over that series&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;No wonder the API suffered from the combinatorial explosion. Now
these things are all done separately:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb13&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb13-1&quot;&gt;&lt;a href=&quot;#cb13-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;generate ::&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;Depth&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; [a]) &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Series&lt;/span&gt; m a&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;can be used to turn a list into a series;&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb14&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb14-1&quot;&gt;&lt;a href=&quot;#cb14-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;over ::&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;Monad&lt;/span&gt; m, &lt;span class=&quot;dt&quot;&gt;Show&lt;/span&gt; a, &lt;span class=&quot;dt&quot;&gt;Testable&lt;/span&gt; m b) &lt;span class=&quot;ot&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Series&lt;/span&gt; m a &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; (a &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; b) &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Property&lt;/span&gt; m&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;sets the domain of quantification; and&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb15&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb15-1&quot;&gt;&lt;a href=&quot;#cb15-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;forAll ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Testable&lt;/span&gt; m a &lt;span class=&quot;ot&quot;&gt;=&amp;gt;&lt;/span&gt; a &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Property&lt;/span&gt; m&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;sets the quantification context.&lt;/p&gt;
</description>
                        <pubDate>Tue, 19 Feb 2013 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2013-02-19-smallcheck</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2013-02-19-smallcheck.html</guid>
                </item>
        
                <item>
                        <title>Generic uncurry</title>
                        <description>&lt;p&gt;For the next version of &lt;a
href=&quot;https://github.com/UnkindPartition/smallcheck&quot;&gt;SmallCheck&lt;/a&gt; I
needed a generic uncurry function in Haskell. To my surprise, I couldn’t
google anything simple and ready to use.&lt;/p&gt;
&lt;p&gt;So here it is, for future reference.&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb1&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb1-1&quot;&gt;&lt;a href=&quot;#cb1-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;{-# LANGUAGE TypeFamilies, DefaultSignatures, UndecidableInstances #-}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-2&quot;&gt;&lt;a href=&quot;#cb1-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Uncurry&lt;/span&gt; a &lt;span class=&quot;kw&quot;&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-3&quot;&gt;&lt;a href=&quot;#cb1-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Uncurried1&lt;/span&gt; b a&lt;/span&gt;
&lt;span id=&quot;cb1-4&quot;&gt;&lt;a href=&quot;#cb1-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Uncurried1&lt;/span&gt; b a &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; b &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; a&lt;/span&gt;
&lt;span id=&quot;cb1-5&quot;&gt;&lt;a href=&quot;#cb1-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-6&quot;&gt;&lt;a href=&quot;#cb1-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;  unc1 ::&lt;/span&gt; (b &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; a) &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Uncurried1&lt;/span&gt; b a&lt;/span&gt;
&lt;span id=&quot;cb1-7&quot;&gt;&lt;a href=&quot;#cb1-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  default&lt;span class=&quot;ot&quot;&gt; unc1 ::&lt;/span&gt; (b &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; a) &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; (b &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; a)&lt;/span&gt;
&lt;span id=&quot;cb1-8&quot;&gt;&lt;a href=&quot;#cb1-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  unc1 &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;id&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-9&quot;&gt;&lt;a href=&quot;#cb1-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-10&quot;&gt;&lt;a href=&quot;#cb1-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Uncurried&lt;/span&gt; a&lt;/span&gt;
&lt;span id=&quot;cb1-11&quot;&gt;&lt;a href=&quot;#cb1-11&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Uncurried&lt;/span&gt; a &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; a&lt;/span&gt;
&lt;span id=&quot;cb1-12&quot;&gt;&lt;a href=&quot;#cb1-12&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-13&quot;&gt;&lt;a href=&quot;#cb1-13&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;  unc ::&lt;/span&gt; a &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Uncurried&lt;/span&gt; a&lt;/span&gt;
&lt;span id=&quot;cb1-14&quot;&gt;&lt;a href=&quot;#cb1-14&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  default&lt;span class=&quot;ot&quot;&gt; unc ::&lt;/span&gt; a &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; a&lt;/span&gt;
&lt;span id=&quot;cb1-15&quot;&gt;&lt;a href=&quot;#cb1-15&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  unc &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;id&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-16&quot;&gt;&lt;a href=&quot;#cb1-16&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-17&quot;&gt;&lt;a href=&quot;#cb1-17&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;instance&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Uncurry&lt;/span&gt; y &lt;span class=&quot;ot&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Uncurry&lt;/span&gt; (x &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; y) &lt;span class=&quot;kw&quot;&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-18&quot;&gt;&lt;a href=&quot;#cb1-18&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Uncurried1&lt;/span&gt; z (x &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; y) &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Uncurried1&lt;/span&gt; (z, x) y&lt;/span&gt;
&lt;span id=&quot;cb1-19&quot;&gt;&lt;a href=&quot;#cb1-19&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  unc1 &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; unc1 &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;uncurry&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-20&quot;&gt;&lt;a href=&quot;#cb1-20&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-21&quot;&gt;&lt;a href=&quot;#cb1-21&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Uncurried&lt;/span&gt; (x &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; y) &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Uncurried1&lt;/span&gt; x y&lt;/span&gt;
&lt;span id=&quot;cb1-22&quot;&gt;&lt;a href=&quot;#cb1-22&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  unc &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; unc1&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;You also need to make the final type an instance of &lt;code
class=&quot;sourceCode haskell&quot;&gt;&lt;span class=&quot;dt&quot;&gt;Uncurry&lt;/span&gt;&lt;/code&gt;. For
example, if you need to uncurry &lt;code
class=&quot;sourceCode haskell&quot;&gt;&lt;span class=&quot;dt&quot;&gt;Int&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Bool&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Double&lt;/span&gt;&lt;/code&gt;,
&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span class=&quot;dt&quot;&gt;Double&lt;/span&gt;&lt;/code&gt;
has to be an instance of &lt;code
class=&quot;sourceCode haskell&quot;&gt;&lt;span class=&quot;dt&quot;&gt;Uncurry&lt;/span&gt;&lt;/code&gt;. But
thanks to &lt;a
href=&quot;http://www.haskell.org/ghc/docs/7.6.2/html/users_guide/type-class-extensions.html#class-default-signatures&quot;&gt;default
method signatures&lt;/a&gt; and &lt;a
href=&quot;http://www.haskell.org/ghc/docs/7.6.2/html/users_guide/type-families.html#assoc-decl-defs&quot;&gt;associated
type synonym defaults&lt;/a&gt;, it is as easy as&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb2&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb2-1&quot;&gt;&lt;a href=&quot;#cb2-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;instance&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Uncurry&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Double&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code
class=&quot;sourceCode haskell&quot;&gt;&lt;span class=&quot;dt&quot;&gt;Uncurry1&lt;/span&gt;&lt;/code&gt; and
&lt;code&gt;unc1&lt;/code&gt; are implementation details. The useful parts are &lt;code
class=&quot;sourceCode haskell&quot;&gt;&lt;span class=&quot;dt&quot;&gt;Uncurry&lt;/span&gt;&lt;/code&gt;, which
converts the type to its uncurried version, and &lt;code
class=&quot;sourceCode haskell&quot;&gt;unc&lt;/code&gt;, which uncurries the function
itself.&lt;/p&gt;
&lt;p&gt;After loading the code in ghci, you can see that it works by:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;*Uncurry&amp;gt; :kind! Uncurried (Int -&amp;gt; Bool -&amp;gt; Char -&amp;gt; Double)
Uncurried (Int -&amp;gt; Bool -&amp;gt; Char -&amp;gt; Double) :: *
= ((Int, Bool), Char) -&amp;gt; Double

*Uncurry&amp;gt; :t unc $ \x y z -&amp;gt; (x + y * z :: Double)
unc $ \x y z -&amp;gt; (x + y * z :: Double)
  :: ((Double, Double), Double) -&amp;gt; Double

*Uncurry&amp;gt; unc (\x y z -&amp;gt; (x + y * z :: Double)) ((1,2),3)
7.0&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I tested this with GHC 7.6, but I think it should work with GHC 7.4
as well.&lt;/p&gt;
</description>
                        <pubDate>Tue, 29 Jan 2013 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2013-01-29-generic-uncurry</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2013-01-29-generic-uncurry.html</guid>
                </item>
        
                <item>
                        <title>Subtractable values are torsors</title>
                        <description>&lt;p&gt;A &lt;strong&gt;group&lt;/strong&gt; is an abstraction for things that can be
«added» and «subtracted» (in some sense).&lt;/p&gt;
&lt;p&gt;Most of the groups that programmers deal with are numeric, although
some interesting groups arise in &lt;a
href=&quot;http://en.wikipedia.org/wiki/Rotation_group_SO(3)&quot;&gt;graphics&lt;/a&gt;
and &lt;a
href=&quot;http://en.wikipedia.org/wiki/Elliptic_Curve_Cryptography&quot;&gt;cryptography&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;If we only require that things can be added, but not subtracted, we
get &lt;strong&gt;semigroups&lt;/strong&gt; and &lt;strong&gt;monoids&lt;/strong&gt; (the
difference is that a monoid also has a «zero» element). These are
plentiful, with applications ranging from &lt;a
href=&quot;http://www.cis.upenn.edu/~byorgey/pub/monoid-pearl.pdf&quot;&gt;diagrams&lt;/a&gt;
to &lt;a href=&quot;http://jkff.info/articles/ire/&quot;&gt;regular expressions&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The reason is, of course, that addition is very natural — we can
consider any way to combine objects together an addition as soon as it
is associative — while subtraction, the inverse of addition, often
doesn’t make sense.&lt;/p&gt;
&lt;h2 id=&quot;dates&quot;&gt;Dates&lt;/h2&gt;
&lt;p&gt;But there are also things that can be subtracted, but not added. The
simplest example is dates. You can subtract two dates to get the time
interval between them, but you cannot add two dates. It doesn’t make
sense to ask what today plus tomorrow is. You could try to add the
numeric values corresponding to the dates and convert the answer back to
a date, but the result would depend on whether you count from the start
of the Common Era, the Unix epoch, or something else.&lt;/p&gt;
&lt;p&gt;While adding two dates is not possible, it is possible to add a time
interval to a date («five days from today»). This suggests that we
should not confound dates and time intervals — they are different types
of values.&lt;/p&gt;
&lt;p&gt;For example, in the Haskell &lt;a
href=&quot;http://hackage.haskell.org/package/time&quot;&gt;time&lt;/a&gt; package, there
are types &lt;a
href=&quot;http://hackage.haskell.org/packages/archive/time/1.4.0.2/doc/html/Data-Time-Clock.html#t:UTCTime&quot;&gt;UTCTime&lt;/a&gt;
and &lt;a
href=&quot;http://hackage.haskell.org/packages/archive/time/1.4.0.2/doc/html/Data-Time-Clock.html#t:NominalDiffTime&quot;&gt;NominalDiffTime&lt;/a&gt;,
and the following functions:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb1&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb1-1&quot;&gt;&lt;a href=&quot;#cb1-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;addUTCTime ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;NominalDiffTime&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;UTCTime&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;UTCTime&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-2&quot;&gt;&lt;a href=&quot;#cb1-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;diffUTCTime ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;UTCTime&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;UTCTime&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;NominalDiffTime&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Time intervals can also be added and subtracted, as witnessed by the
&lt;code
class=&quot;sourceCode haskell&quot;&gt;&lt;span class=&quot;dt&quot;&gt;Num&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;NominalDiffTime&lt;/span&gt;&lt;/code&gt;
instance.&lt;/p&gt;
&lt;h2 id=&quot;ask-mathematics&quot;&gt;Ask mathematics&lt;/h2&gt;
&lt;p&gt;What is the mathematical notion that characterizes dates? It should
involve two sets: the set &lt;span class=&quot;math inline&quot;&gt;\(V\)&lt;/span&gt; of
values and the set &lt;span class=&quot;math inline&quot;&gt;\(D\)&lt;/span&gt; of value
differences.&lt;/p&gt;
&lt;p&gt;The set &lt;span class=&quot;math inline&quot;&gt;\(D\)&lt;/span&gt; must form an additive
group, so that we can add and subtract the differences. (The word
«additive» means that we assume that the group operation, identity
element and inverse operation are called &lt;span
class=&quot;math inline&quot;&gt;\(+\)&lt;/span&gt;, &lt;span class=&quot;math inline&quot;&gt;\(0\)&lt;/span&gt;
and &lt;span class=&quot;math inline&quot;&gt;\(−\)&lt;/span&gt; respectively. In group theory
it is more common to call them &lt;span
class=&quot;math inline&quot;&gt;\(\cdot\)&lt;/span&gt;, &lt;span
class=&quot;math inline&quot;&gt;\(1\)&lt;/span&gt; and &lt;span
class=&quot;math inline&quot;&gt;\({}^{-1}\)&lt;/span&gt;.)&lt;/p&gt;
&lt;p&gt;Thus we have the “zero” difference &lt;span class=&quot;math inline&quot;&gt;\(0\in
D\)&lt;/span&gt; and operations &lt;span class=&quot;math inline&quot;&gt;\(+\colon D\times
D\to D\)&lt;/span&gt;, &lt;span class=&quot;math inline&quot;&gt;\(-\colon D\to D\)&lt;/span&gt;
which satisfy the usual group laws:&lt;/p&gt;
&lt;dl&gt;
&lt;dt&gt;&lt;span class=&quot;math inline&quot;&gt;\(+/0\)&lt;/span&gt; (identity element)&lt;/dt&gt;
&lt;dd&gt;
&lt;p&gt;&lt;span class=&quot;math inline&quot;&gt;\(0+x=x+0=x\)&lt;/span&gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;&lt;span class=&quot;math inline&quot;&gt;\(+/+\)&lt;/span&gt; (associativity)&lt;/dt&gt;
&lt;dd&gt;
&lt;p&gt;&lt;span class=&quot;math inline&quot;&gt;\((x+y)+z=x+(y+z)\)&lt;/span&gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;&lt;span class=&quot;math inline&quot;&gt;\(+/−\)&lt;/span&gt; (inverse element)&lt;/dt&gt;
&lt;dd&gt;
&lt;p&gt;&lt;span class=&quot;math inline&quot;&gt;\(x+(−x)=(−x)+x=0\)&lt;/span&gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;(We can write &lt;span class=&quot;math inline&quot;&gt;\(x−y\)&lt;/span&gt; as a shorthand
for &lt;span class=&quot;math inline&quot;&gt;\(x+(−y)\)&lt;/span&gt;.)&lt;/p&gt;
&lt;p&gt;We do not require &lt;span class=&quot;math inline&quot;&gt;\(+\)&lt;/span&gt; to be
commutative to preserve generality, even though it is commutative for
our current example.&lt;/p&gt;
&lt;p&gt;We need to be able to add a difference to a value. Thus, we need a
function &lt;span class=&quot;math inline&quot;&gt;\(\mathrm{add}:D\times V\to
V\)&lt;/span&gt;. We would expect it to play well with the group structure of
&lt;span class=&quot;math inline&quot;&gt;\(D\)&lt;/span&gt;:&lt;/p&gt;
&lt;dl&gt;
&lt;dt&gt;&lt;span class=&quot;math inline&quot;&gt;\(\mathrm{add}/0\)&lt;/span&gt;&lt;/dt&gt;
&lt;dd&gt;
&lt;p&gt;&lt;span class=&quot;math inline&quot;&gt;\(\mathrm{add}(0,v)=v\)&lt;/span&gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;&lt;span class=&quot;math inline&quot;&gt;\(\mathrm{add}/+\)&lt;/span&gt;&lt;/dt&gt;
&lt;dd&gt;
&lt;p&gt;&lt;span
class=&quot;math inline&quot;&gt;\(\mathrm{add}(x+y,v)=\mathrm{add}(x,\mathrm{add}(y,v))\)&lt;/span&gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;An alternative view on these laws is that the curried version of
&lt;span class=&quot;math inline&quot;&gt;\(\mathrm{add}\)&lt;/span&gt;, &lt;span
class=&quot;math inline&quot;&gt;\(\mathrm{curry}(\mathrm{add}):D→(V→V)\)&lt;/span&gt;, is
a group homomorphism from &lt;span class=&quot;math inline&quot;&gt;\(D\)&lt;/span&gt; to the
group of bijections on &lt;span class=&quot;math inline&quot;&gt;\(V\)&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;The mathematical abstraction corresponding to our &lt;span
class=&quot;math inline&quot;&gt;\(\mathrm{add}\)&lt;/span&gt; function is an &lt;a
href=&quot;http://en.wikipedia.org/wiki/Group_action&quot;&gt;&lt;strong&gt;action&lt;/strong&gt;&lt;/a&gt;
of group &lt;span class=&quot;math inline&quot;&gt;\(D\)&lt;/span&gt; on the set &lt;span
class=&quot;math inline&quot;&gt;\(V\)&lt;/span&gt;. But it doesn’t yet capture the fact
that we can subtract two values to get a difference. For that we need a
function &lt;span class=&quot;math inline&quot;&gt;\(\mathrm{diff}:V×V→D\)&lt;/span&gt;
inverse to &lt;span class=&quot;math inline&quot;&gt;\(\mathrm{add}\)&lt;/span&gt;:&lt;/p&gt;
&lt;dl&gt;
&lt;dt&gt;&lt;span class=&quot;math inline&quot;&gt;\(\mathrm{diff}/\mathrm{add}\)&lt;/span&gt;&lt;/dt&gt;
&lt;dd&gt;
&lt;p&gt;&lt;span
class=&quot;math inline&quot;&gt;\(\mathrm{diff}(\mathrm{add}(x,v),v)=x\)&lt;/span&gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;&lt;span class=&quot;math inline&quot;&gt;\(\mathrm{add}/\mathrm{diff}\)&lt;/span&gt;&lt;/dt&gt;
&lt;dd&gt;
&lt;p&gt;&lt;span
class=&quot;math inline&quot;&gt;\(\mathrm{add}(\mathrm{diff}(u,v),v)=u\)&lt;/span&gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;If such a function exists, the set &lt;span
class=&quot;math inline&quot;&gt;\(V\)&lt;/span&gt; is called a &lt;strong&gt;torsor&lt;/strong&gt;
over the group &lt;span class=&quot;math inline&quot;&gt;\(D\)&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;Thus, it is the mathematical notion of torsor that characterizes
subtractable values.&lt;/p&gt;
&lt;p&gt;Conal Elliott &lt;a
href=&quot;http://hackage.haskell.org/packages/archive/vector-space/latest/doc/html/Data-AffineSpace.html&quot;&gt;defines&lt;/a&gt;
torsors in Haskell under the name of affine spaces.&lt;/p&gt;
&lt;h2 id=&quot;other-examples&quot;&gt;Other examples&lt;/h2&gt;
&lt;h3 id=&quot;points&quot;&gt;Points&lt;/h3&gt;
&lt;p&gt;Another simple example of a torsor is points. In linear algebra we
get used to conflating points and vectors, because we consider vectors
originating at zero.&lt;/p&gt;
&lt;p&gt;But the geometrical intuition suggests that vectors do not have to be
tied to zero. A vector is a directed segment which can be freely
translated (shifted) on the plane (or in the space).&lt;/p&gt;
&lt;p&gt;We can subtract two points to get a vector from one point to another.
We can add a vector to a point, by translating it so that its origin
becomes the given point. The end point of the vector then becomes the
result of addition.&lt;/p&gt;
&lt;p&gt;Vectors form an additive group, and points form a torsor over the
vectors.&lt;/p&gt;
&lt;p&gt;Like with dates, results of torsor operations on points and vectors
do not depend on (and do not require the existence of) a coordinate
system, while the «sum» of two points will change if you change the
origin.&lt;/p&gt;
&lt;h3 id=&quot;files&quot;&gt;Files&lt;/h3&gt;
&lt;p&gt;There are also some examples that look very much like torsors, but do
not satisfy all the laws.&lt;/p&gt;
&lt;p&gt;One of such examples is files. The difference of two files is what we
call a patch, or a diff. We can diff two files and apply the resulting
patch to a third file («cherry-picking»).&lt;/p&gt;
&lt;p&gt;Although patches do not form a group, they can be modelled as &lt;a
href=&quot;http://www.math.ucla.edu/~jjacobson/patch-theory/patch-semigroups.pdf&quot;&gt;inverse
semigroups&lt;/a&gt;. This motivates us to consider &lt;a
href=&quot;http://mysite.science.uottawa.ca/phofstra/semigrouptorsors.pdf&quot;&gt;torsors
based on inverse semigroups&lt;/a&gt; rather than on groups.&lt;/p&gt;
&lt;h3 id=&quot;haskell-dialects&quot;&gt;Haskell dialects&lt;/h3&gt;
&lt;p&gt;Haskell dialects can be considered as a torsor-like structure over
Haskell extensions. We can add extensions to languages:&lt;/p&gt;
&lt;p&gt;&lt;span
class=&quot;math display&quot;&gt;\[\mathrm{add}(\mathrm{RankNTypes}+\mathrm{GADTs}−\mathrm{MonomorphismRestriction},
\mathrm{Haskell2010}).\]&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;We can also subtract two languages to find out the difference between
them in terms of extensions: &lt;span class=&quot;math display&quot;&gt;\[
\begin{align*}
\mathrm{diff}(\mathrm{Haskell2010}, \mathrm{Haskell98}) &amp;amp; =
\mathrm{DoAndIfThenElse} \\
&amp;amp; +\mathrm{PatternGuards} \\
&amp;amp; +\mathrm{ForeignFunctionInterface} \\
&amp;amp; +\mathrm{EmptyDataDecls} \\
&amp;amp; −\mathrm{NPlusKPatterns}.
\end{align*}
\]&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Extensions do not form a group. The easiest way to see that is to
observe that extensions are idempotent, i.e. &lt;span
class=&quot;math inline&quot;&gt;\(X+X=X\)&lt;/span&gt; for any extension &lt;span
class=&quot;math inline&quot;&gt;\(X\)&lt;/span&gt;. However, in a group there is only one
idempotent element, zero.&lt;/p&gt;
&lt;p&gt;Extensions do form an inverse semigroup, though. Thus we again arrive
at inverse semigroup torsors.&lt;/p&gt;
&lt;h2 id=&quot;acknowledgements&quot;&gt;Acknowledgements&lt;/h2&gt;
&lt;p&gt;A recent discussion with &lt;a href=&quot;http://www.nbroberg.se/&quot;&gt;Niklas
Broberg&lt;/a&gt; about Haskell extensions motivated me to explore these
concepts. His &lt;a
href=&quot;http://www.youtube.com/watch?v=MoxqBGaTmWQ&quot;&gt;HIW’12 lightning
talk&lt;/a&gt; on Haskell Modular Mindset is also relevant.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://oleksandrmanzyuk.wordpress.com/&quot;&gt;Oleksandr
Manzyuk&lt;/a&gt; kindly pointed me to the concept of a torsor.&lt;/p&gt;
</description>
                        <pubDate>Tue, 08 Jan 2013 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2013-01-08-torsors</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2013-01-08-torsors.html</guid>
                </item>
        
                <item>
                        <title>Monads in dynamic languages</title>
                        <description>&lt;p&gt;Are monads possible outside of Haskell?&lt;/p&gt;
&lt;p&gt;Of course, it depends on what you call a monad.&lt;/p&gt;
&lt;p&gt;The definition that is usually accepted in the Haskell context — that
a monad is an instance of the particular type constructor class,
&lt;code&gt;Monad&lt;/code&gt;, with two methods satisfying three laws — is very
much tied to Haskell’s language features — most importantly, types, type
constructors and type constructor classes. Hence, this or similar notion
of monad can only exist in a language rather close to Haskell.&lt;/p&gt;
&lt;p&gt;If we drop the type constructor class requirement, then a monad is a
triple consisting of a type constructor &lt;code&gt;M&lt;/code&gt; and two
polymorphic functions&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;return :: forall a . a -&amp;gt; M a
(&amp;gt;&amp;gt;=) :: forall a b . M a -&amp;gt; (a -&amp;gt; M b) -&amp;gt; M b&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is the definition originally used by Wadler in &lt;a
href=&quot;http://homepages.inf.ed.ac.uk/wadler/papers/essence/essence.ps&quot;&gt;The
essence of functional programming&lt;/a&gt;. By this definition, Monads can be
implemented in other Hindley-Milner based languages, like Miranda and &lt;a
href=&quot;http://existentialtype.wordpress.com/2011/05/01/of-course-ml-has-monads/&quot;&gt;ML&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;But what if we take this to extreme? What if we consider a
dynamically typed functional language?&lt;/p&gt;
&lt;p&gt;A dynamically typed language is &lt;a
href=&quot;http://existentialtype.wordpress.com/2011/03/19/dynamic-languages-are-static-languages/&quot;&gt;nothing
else than a static language&lt;/a&gt; with a single type, which we shall call
here &lt;code&gt;U&lt;/code&gt;. Thus, the signatures of &lt;code&gt;&amp;gt;&amp;gt;=&lt;/code&gt; and
&lt;code&gt;return&lt;/code&gt; become&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;return :: U -&amp;gt; U
(&amp;gt;&amp;gt;=) :: U -&amp;gt; (U -&amp;gt; U) -&amp;gt; U&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;(We could as well say that &lt;code&gt;&amp;gt;&amp;gt;=&lt;/code&gt; and
&lt;code&gt;return&lt;/code&gt; both have type &lt;code&gt;U&lt;/code&gt; — remember, there’s
only one type!) The functions themselves are still presumed to satisfy
the usual laws.&lt;/p&gt;
&lt;p&gt;This has been done &lt;a
href=&quot;http://lambda-the-ultimate.org/node/1136&quot;&gt;many times&lt;/a&gt; before,
most recent example being &lt;a
href=&quot;http://www.youtube.com/watch?v=dkZFtimgAcM&quot;&gt;Douglas Crockford’s
keynote at YUIConf&lt;/a&gt;. Douglas’s presentation has received a lot of
criticism (and I’m not going to defend him), but some critics even have
expressed the doubt that these are not «genuine» monads.&lt;/p&gt;
&lt;p&gt;To settle this, let’s turn to the category theory — after all, that’s
where monads come from. Haskell’s monads are category theory monads,
where the type constructor is considered as an endofunctor on Hask, the
category of Haskell types and functions.&lt;/p&gt;
&lt;p&gt;What changes when we go from Haskell to a unityped language is that
all the diversity of Haskell types collapses into the single type,
&lt;code&gt;U&lt;/code&gt;. That doesn’t stop it from forming a category, though.
Because it has a single object, we don’t need a type constructor to
represent the functorial action on objects — it’s always identity. We
only need to know the functorial action on arrows (called
&lt;code&gt;fmap&lt;/code&gt; in Haskell) — but it is already determined by
&lt;code&gt;return&lt;/code&gt; and &lt;code&gt;&amp;gt;&amp;gt;=&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;To summarize, there doesn’t seem to be any reason to think that
monads are somehow impossible in dynamic functional languages. And,
although Haskellers usually consider monads as something closely tied to
types, in a dynamic language all you need to define a monad is to define
a pair of functions satisfying the monad laws.&lt;/p&gt;
</description>
                        <pubDate>Wed, 26 Dec 2012 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2012-12-26-monads-in-dynamic-languages</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2012-12-26-monads-in-dynamic-languages.html</guid>
                </item>
        
                <item>
                        <title>Surprises of the Haskell module system (part 1)</title>
                        <description>&lt;p&gt;While the basics of the Haskell module system are easy to understand,
there are certainly interesting corner cases and non-obvious
(mis)features.&lt;/p&gt;
&lt;p&gt;All of these are documented in the &lt;a
href=&quot;http://www.haskell.org/onlinereport/haskell2010/haskellch5.html&quot;&gt;Haskell
report&lt;/a&gt;, but the tricky details may be hard to notice. Another good
read on this subject is &lt;a
href=&quot;http://web.cecs.pdx.edu/~mpj/pubs/hsmods.pdf&quot;&gt;A Formal
Specification for the Haskell 98 Module System&lt;/a&gt; by Iavor S. Diatchki,
Mark P. Jones, and Thomas Hallgren.&lt;/p&gt;
&lt;h2 id=&quot;empty-module-header&quot;&gt;Empty module header&lt;/h2&gt;
&lt;p&gt;What happens when the export list is omitted, like in the following
example?&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb1&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb1-1&quot;&gt;&lt;a href=&quot;#cb1-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;module&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;M&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-2&quot;&gt;&lt;a href=&quot;#cb1-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-3&quot;&gt;&lt;a href=&quot;#cb1-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;foo &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;42&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This one is easy: all the locally defined types, classes and values
are exported.&lt;/p&gt;
&lt;p&gt;We might assume that something similar happens when we omit the
module header altogether, like if we put&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb2&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb2-1&quot;&gt;&lt;a href=&quot;#cb2-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;foo &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;42&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;in a file by itself.&lt;/p&gt;
&lt;p&gt;Contrary to this intuition, and according to the standard, when you
omit the module header, it is assumed to be &lt;code
class=&quot;sourceCode haskell&quot;&gt;&lt;span class=&quot;kw&quot;&gt;module&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Main&lt;/span&gt;(main) &lt;span class=&quot;kw&quot;&gt;where&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Sometimes you want to check whether a piece of Haskell code compiles.
You may put it into a file and try &lt;code&gt;ghc test.hs&lt;/code&gt;. But even if
the code itself doesn’t contain errors, you’ll get a message&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;test.hs:1:1: The function `main&amp;#39; is not defined in module `Main&amp;#39;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The message may seem confusing at first: what’s the module
&lt;code&gt;Main&lt;/code&gt; it’s talking about, and why do I need this
&lt;code&gt;main&lt;/code&gt; function? Well, now you know the answer.&lt;/p&gt;
&lt;h2 id=&quot;module-re-exports&quot;&gt;Module re-exports&lt;/h2&gt;
&lt;p&gt;You probably know that you can re-export a whole module from your own
module. The syntax is&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb4&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb4-1&quot;&gt;&lt;a href=&quot;#cb4-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;module&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;M&lt;/span&gt; (&lt;span class=&quot;kw&quot;&gt;module&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;N&lt;/span&gt;) &lt;span class=&quot;kw&quot;&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-2&quot;&gt;&lt;a href=&quot;#cb4-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;op&quot;&gt;...&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The semantics of this re-export is a bit tricky, though. For example,
what can we say about the following module?&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb5&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb5-1&quot;&gt;&lt;a href=&quot;#cb5-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;module&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;M&lt;/span&gt; (&lt;span class=&quot;kw&quot;&gt;module&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Data.List&lt;/span&gt;) &lt;span class=&quot;kw&quot;&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb5-2&quot;&gt;&lt;a href=&quot;#cb5-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;qualified&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Data.List&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;You’d probably think that module &lt;code&gt;M&lt;/code&gt; now exports
everything that is exported by &lt;code&gt;Data.List&lt;/code&gt;. Not at all! The
standard says (emphasis is mine):&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The form &lt;code&gt;module M&lt;/code&gt; names the set of all entities that are
in scope with &lt;em&gt;both&lt;/em&gt; an unqualified name &lt;code&gt;e&lt;/code&gt; and a
qualified name &lt;code&gt;M.e&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Since we imported &lt;code&gt;Data.List&lt;/code&gt; qualified, nothing from it
is in scope under an unqualified name. So, &lt;code&gt;M&lt;/code&gt; doesn’t export
anything. Right? Not quite.&lt;/p&gt;
&lt;p&gt;The last thing we need to observe here is that although the single
module imported by &lt;code&gt;M&lt;/code&gt; explicitly is &lt;code&gt;Data.List&lt;/code&gt;,
there’s always an implicit import — &lt;code&gt;Prelude&lt;/code&gt;. And these two
share quite a lot in common — functions like &lt;code&gt;foldr&lt;/code&gt;,
&lt;code&gt;map&lt;/code&gt;, &lt;code&gt;length&lt;/code&gt; etc. All these satisfy the
criterion above — they are in scope with both unqualified and qualified
names, although these names come from different modules.&lt;/p&gt;
&lt;p&gt;To summarize, the module &lt;code&gt;M&lt;/code&gt; defined above will export
exactly the intersection of &lt;code&gt;Prelude&lt;/code&gt; and
&lt;code&gt;Data.List&lt;/code&gt;, plus instances exported by either of these
modules.&lt;/p&gt;
</description>
                        <pubDate>Tue, 25 Dec 2012 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2012-12-25-haskell-module-system-p1</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2012-12-25-haskell-module-system-p1.html</guid>
                </item>
        
                <item>
                        <title>Haskell recipe: reading list of lines
</title>
                        <description>&lt;div class=&quot;sourceCode&quot; id=&quot;cb1&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb1-1&quot;&gt;&lt;a href=&quot;#cb1-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Prelude&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;hiding&lt;/span&gt; (readList)&lt;/span&gt;
&lt;span id=&quot;cb1-2&quot;&gt;&lt;a href=&quot;#cb1-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Control.Applicative&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-3&quot;&gt;&lt;a href=&quot;#cb1-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Control.Monad&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-4&quot;&gt;&lt;a href=&quot;#cb1-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Control.Monad.Trans&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-5&quot;&gt;&lt;a href=&quot;#cb1-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Control.Monad.Trans.Maybe&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-6&quot;&gt;&lt;a href=&quot;#cb1-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Data.Maybe&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Suppose we need to ask the user to enter a list of lines, terminated
by an empty line. The usual way to do it is through recursion:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb2&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb2-1&quot;&gt;&lt;a href=&quot;#cb2-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;fu&quot;&gt;readList&lt;/span&gt;&lt;span class=&quot;ot&quot;&gt; ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;IO&lt;/span&gt; [&lt;span class=&quot;dt&quot;&gt;String&lt;/span&gt;]&lt;/span&gt;
&lt;span id=&quot;cb2-2&quot;&gt;&lt;a href=&quot;#cb2-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;fu&quot;&gt;readList&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-3&quot;&gt;&lt;a href=&quot;#cb2-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  l &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;getLine&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb2-4&quot;&gt;&lt;a href=&quot;#cb2-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;null&lt;/span&gt; l&lt;/span&gt;
&lt;span id=&quot;cb2-5&quot;&gt;&lt;a href=&quot;#cb2-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;kw&quot;&gt;then&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;return&lt;/span&gt; []&lt;/span&gt;
&lt;span id=&quot;cb2-6&quot;&gt;&lt;a href=&quot;#cb2-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;kw&quot;&gt;else&lt;/span&gt; (l &lt;span class=&quot;op&quot;&gt;:&lt;/span&gt;) &lt;span class=&quot;op&quot;&gt;&amp;lt;$&amp;gt;&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;readList&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This is fine, but can we do better?&lt;/p&gt;
&lt;p&gt;A good style in Haskell is to replace explicit recursion with
high-level recursion combinators where it is possible and doesn’t harm
readability.&lt;/p&gt;
&lt;p&gt;What is the pattern here? Those who are familiar with parser
combinator libraries will easily recognize the &lt;code&gt;many&lt;/code&gt;
combinator. It tries to recognize as many items as possible and returns
the list of recognized items (in this case successful recognition means
that we got a non-empty line).&lt;/p&gt;
&lt;p&gt;A generalization of the &lt;code&gt;many&lt;/code&gt; combinator works for any
applicative functor which is an instance of the &lt;code&gt;Alternative&lt;/code&gt;
class:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb3&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb3-1&quot;&gt;&lt;a href=&quot;#cb3-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;many ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Alternative&lt;/span&gt; f &lt;span class=&quot;ot&quot;&gt;=&amp;gt;&lt;/span&gt; f a &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; f [a]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The &lt;code&gt;IO&lt;/code&gt; functor is not an instance of
&lt;code&gt;Alternative&lt;/code&gt;, but we can fix it by layering a
&lt;code&gt;MaybeT&lt;/code&gt; transformer on top of it. &lt;code&gt;MaybeT&lt;/code&gt; will
be our means to distinguish failure from success.&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb4&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb4-1&quot;&gt;&lt;a href=&quot;#cb4-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;fu&quot;&gt;readList&lt;/span&gt;&lt;span class=&quot;ot&quot;&gt; ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;IO&lt;/span&gt; [&lt;span class=&quot;dt&quot;&gt;String&lt;/span&gt;]&lt;/span&gt;
&lt;span id=&quot;cb4-2&quot;&gt;&lt;a href=&quot;#cb4-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;fu&quot;&gt;readList&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;fmap&lt;/span&gt; (fromMaybe []) &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; runMaybeT &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; many &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-3&quot;&gt;&lt;a href=&quot;#cb4-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  l &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; lift &lt;span class=&quot;fu&quot;&gt;getLine&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb4-4&quot;&gt;&lt;a href=&quot;#cb4-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  guard &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;not&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;null&lt;/span&gt; l&lt;/span&gt;
&lt;span id=&quot;cb4-5&quot;&gt;&lt;a href=&quot;#cb4-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;fu&quot;&gt;return&lt;/span&gt; l&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The inner &lt;code&gt;do&lt;/code&gt;-block is the code which reads one line,
and, depending on whether that line is null, returns it or signals about
the failure.&lt;/p&gt;
&lt;p&gt;Some more details about what’s going on there.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;lift getLine&lt;/code&gt; lifts &lt;code&gt;getLine&lt;/code&gt; from
&lt;code&gt;IO String&lt;/code&gt; to &lt;code&gt;MaybeT IO String&lt;/code&gt; by assuming that
it always succeeds (in &lt;code&gt;MaybeT&lt;/code&gt; sense).&lt;/li&gt;
&lt;li&gt;&lt;code&gt;guard&lt;/code&gt; is a function from the &lt;code&gt;MonadZero&lt;/code&gt;
class that checks the condition and, if it does not hold, declares
failure. It is somewhat similar to an &lt;code&gt;assert&lt;/code&gt; function,
except it is used for control flow rather than debugging purposes.&lt;/li&gt;
&lt;li&gt;Finally, if &lt;code&gt;guard&lt;/code&gt; did not abort the computation, we get
to the last line that simply returns the line we’ve just read.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;(If you want to learn more about how monad transformers work, please
refer to &lt;a href=&quot;/articles/2012-01-02-composing-monads&quot;&gt;Composing
monadic effects&lt;/a&gt;.)&lt;/p&gt;
&lt;p&gt;The outer code does boring stuff: &lt;code&gt;runMaybeT&lt;/code&gt; transforms
&lt;code&gt;MaybeT IO String&lt;/code&gt; to &lt;code&gt;IO (Maybe String)&lt;/code&gt; (which
is the same thing but &lt;code&gt;newtype&lt;/code&gt;d), and &lt;code&gt;fromMaybe&lt;/code&gt;
interprets &lt;code&gt;Nothing&lt;/code&gt; as the empty list.&lt;/p&gt;
&lt;p&gt;It is interesting that only the first line of &lt;code&gt;readList&lt;/code&gt;
definition gives us a hint that &lt;code&gt;MaybeT&lt;/code&gt; works here. The rest
of the code just uses overloaded functions &lt;code&gt;many&lt;/code&gt;,
&lt;code&gt;lift&lt;/code&gt;, &lt;code&gt;guard&lt;/code&gt; and &lt;code&gt;return&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Was the rewrite worth it? It is debatable, since a function did get a
bit more complicated. But in my opinion, the answer is yes — we got rid
of explicit recursion, and the idea of the function became more
clear.&lt;/p&gt;
</description>
                        <pubDate>Thu, 25 Oct 2012 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2012-10-25-reading-list-of-lines</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2012-10-25-reading-list-of-lines.html</guid>
                </item>
        
                <item>
                        <title>Reasoning about space usage in Haskell</title>
                        <description>&lt;p&gt;This article describes why it’s hard to reason about space usage of
Haskell programs.&lt;/p&gt;
&lt;h2 id=&quot;operational-semantics&quot;&gt;Operational semantics&lt;/h2&gt;
&lt;p&gt;The standard (“The Haskell Report”) does not specify an operational
semantics for Haskell. Thus, in order to talk about space usage of
Haskell programs, we need to fix a particular semantics. A good choice
is the STG semantics as defined in the &lt;a
href=&quot;http://community.haskell.org/~simonmar/papers/evalapplyjfp06.pdf&quot;&gt;fast
curry paper&lt;/a&gt;. First, it is formally defined; second, it has
significant practical value, since it is used in GHC, the de-facto
standard Haskell compiler.&lt;/p&gt;
&lt;p&gt;Note, however, that the STG operational semantics is defined for STG
programs, not Haskell programs (STG defines its own small functional
language). It’s not always obvious what STG program corresponds to a
given Haskell program because of numerous optimizations performed by the
compiler, but GHC allows to see the resulting STG code using the
&lt;code&gt;-ddump-stg&lt;/code&gt; flag.&lt;/p&gt;
&lt;h2 id=&quot;operational-properties-are-context-dependent&quot;&gt;Operational
properties are context-dependent&lt;/h2&gt;
&lt;p&gt;In eager languages, usually we can easily express time and space
complexity, e.g. using O-notation.&lt;/p&gt;
&lt;p&gt;In Haskell, operational properties are largely context-dependent, and
there’s no existing framework to express them.&lt;/p&gt;
&lt;h3 id=&quot;laziness&quot;&gt;Laziness&lt;/h3&gt;
&lt;p&gt;One source of context dependency is a direct consequence of lazy
evaluation: the function result may be evaluated to different extents by
different callers.&lt;/p&gt;
&lt;p&gt;For example, it may seem that &lt;code&gt;[1..n]&lt;/code&gt; requires O(n)
memory, but when called from &lt;code&gt;take m [1..n]&lt;/code&gt;, it takes only
O(min(m,n)) memory.&lt;/p&gt;
&lt;h3 id=&quot;garbage-collection&quot;&gt;Garbage collection&lt;/h3&gt;
&lt;p&gt;Another source of context dependency is interaction between laziness
and automatic memory management.&lt;/p&gt;
&lt;p&gt;For example, the following two functions look equivalent in terms of
space usage (although the second one is somewhat less
time-efficient):&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb1&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb1-1&quot;&gt;&lt;a href=&quot;#cb1-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;f1 list &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; foldl&amp;#39; (\(&lt;span class=&quot;op&quot;&gt;!&lt;/span&gt;a,&lt;span class=&quot;op&quot;&gt;!&lt;/span&gt;b) x &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; (a &lt;span class=&quot;op&quot;&gt;+&lt;/span&gt; x, b &lt;span class=&quot;op&quot;&gt;*&lt;/span&gt; x)) (&lt;span class=&quot;dv&quot;&gt;0&lt;/span&gt;, &lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;) list&lt;/span&gt;
&lt;span id=&quot;cb1-2&quot;&gt;&lt;a href=&quot;#cb1-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb1-3&quot;&gt;&lt;a href=&quot;#cb1-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;f2 list &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; (foldl&amp;#39; (\a x &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; a &lt;span class=&quot;op&quot;&gt;+&lt;/span&gt; x) &lt;span class=&quot;dv&quot;&gt;0&lt;/span&gt; list, foldl&amp;#39; (\b x &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; b &lt;span class=&quot;op&quot;&gt;*&lt;/span&gt; x) &lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt; list)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;It would seem that these functions run in constant space. Of course,
by “constant space” we really mean “constant additional space” – we do
not count the space occupied by the list itself, because the function
doesn’t create the list. Well, in a lazy language it does!&lt;/p&gt;
&lt;p&gt;The difference becomes clear if we consider &lt;code&gt;f1 [1..n]&lt;/code&gt;
and &lt;code&gt;f2 [1..n]&lt;/code&gt;: the former indeed runs in constant space,
while the latter requires linear space.&lt;/p&gt;
&lt;p&gt;The reason is that &lt;code&gt;f1&lt;/code&gt; can process the list
incrementally. It demands the next value from the list, updates its
accumulators and throws the value away.&lt;/p&gt;
&lt;p&gt;In &lt;code&gt;f2&lt;/code&gt;, the first fold evaluates the list, but it has to
be kept in memory to be used for the second fold. As a result, by the
time the first fold is evaluated, the whole list is evaluated and none
of it is garbage collected.&lt;/p&gt;
&lt;h3 id=&quot;thunks&quot;&gt;Thunks&lt;/h3&gt;
&lt;p&gt;It’s not enough to track how much space our data occupies. Another
kind of heap inhabitants is thunks. When more thunks are created than
necessary, we have a &lt;a
href=&quot;http://blog.ezyang.com/2011/05/anatomy-of-a-thunk-leak/&quot;&gt;thunk
leak&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;By the way, how many thunks may be necessary? Are there examples
where having more than O(1) thunks at some point of program execution is
the best solution to the problem? I don’t know yet.&lt;/p&gt;
&lt;p&gt;In any case, we need to be able to reason about the number of thunks
that are created by a function.&lt;/p&gt;
&lt;p&gt;To complicate things further, creation of thunks depends on how the
function result is evaluated. For example, a function returns a (lazy)
tuple. We force the first element of that tuple. During the evaluation,
everything that is needed to evaluate that first element is evaluated
immediately, but values needed only for the second element are stored in
thunks.&lt;/p&gt;
&lt;p&gt;If we evaluated the second element, the picture would be dual, and
the number of thunks probably would be different.&lt;/p&gt;
&lt;h2 id=&quot;conclusions&quot;&gt;Conclusions&lt;/h2&gt;
&lt;p&gt;Currently, if we want to reason about space usage of Haskell
programs, we need:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;study the source code of each function. A function documentation
typically includes its type, denotational semantics and perhaps some
O-figures, but that’s not enough, as we’ve seen;&lt;/li&gt;
&lt;li&gt;for each function, understand how its result is evaluated by all
callers.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Clearly, this breaks abstraction and modularity.&lt;/p&gt;
&lt;p&gt;In practice, GHC’s strictness analyser is very smart, so most of the
time we don’t notice any problems. Still, it’s very important to have a
framework in which we could analyse and document functions’ operational
behaviour in a modular and composable way.&lt;/p&gt;
</description>
                        <pubDate>Sun, 08 Apr 2012 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2012-04-08-space-usage-reasoning</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2012-04-08-space-usage-reasoning.html</guid>
                </item>
        
                <item>
                        <title>Composing monadic effects</title>
                        <description>&lt;p&gt;In Haskell, monad transformers are used to combine effects provided
by multiple monads.&lt;/p&gt;
&lt;h2 id=&quot;boring-example-writer-reader-state&quot;&gt;Boring example: Writer,
Reader, State&lt;/h2&gt;
&lt;p&gt;For instance, if we want to have a read-only environment plus a
write-only logging facility, we can start with the Reader monad and add
a logging facility to it with the WriterT monad transformer:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb1&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb1-1&quot;&gt;&lt;a href=&quot;#cb1-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;MyMonad&lt;/span&gt; w r a &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;WriterT&lt;/span&gt; w (&lt;span class=&quot;dt&quot;&gt;Reader&lt;/span&gt; r) a&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Or, we could start with the Writer monad and put the ReaderT
transformer on top of it:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb2&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb2-1&quot;&gt;&lt;a href=&quot;#cb2-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;MyMonad&lt;/span&gt; w r a &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;ReaderT&lt;/span&gt; r (&lt;span class=&quot;dt&quot;&gt;Writer&lt;/span&gt; w) a&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;In the end, it doesn’t matter which way we choose, as both are
isomorphic to&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb3&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb3-1&quot;&gt;&lt;a href=&quot;#cb3-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;MyMonad&lt;/span&gt; w r a &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; r &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; (a, w)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;If we want to have a state as well, we can plug in the StateT
transformer anywhere in the stack, and again the order doesn’t matter.
The resulting monad is now isomorphic to the standard &lt;a
href=&quot;http://hackage.haskell.org/packages/archive/transformers/latest/doc/html/Control-Monad-Trans-RWS-Lazy.html&quot;&gt;RWS&lt;/a&gt;
(Reader-Writer-State) monad.&lt;/p&gt;
&lt;p&gt;So, we say about those transformers that they &lt;em&gt;commute&lt;/em&gt;
(recall that Reader is just the ReaderT transformer applied to the
Identity monad).&lt;/p&gt;
&lt;h2 id=&quot;more-interesting-example-either-writer&quot;&gt;More interesting
example: Either + Writer&lt;/h2&gt;
&lt;p&gt;Not every two transformers commute, though.&lt;/p&gt;
&lt;p&gt;Suppose we want to write log messages, plus to be able to abort the
computation.&lt;/p&gt;
&lt;p&gt;There are two quite different ways to compose these effects.&lt;/p&gt;
&lt;p&gt;There’s&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb4&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb4-1&quot;&gt;&lt;a href=&quot;#cb4-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;MyMonad&lt;/span&gt; e w a &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;ErrorT&lt;/span&gt; e (&lt;span class=&quot;dt&quot;&gt;Writer&lt;/span&gt; w) a&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;isomorphic to &lt;code
class=&quot;sourceCode haskell&quot;&gt;(&lt;span class=&quot;dt&quot;&gt;Either&lt;/span&gt; e a, w)&lt;/code&gt;,
and then there’s&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb5&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb5-1&quot;&gt;&lt;a href=&quot;#cb5-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;MyMonad&lt;/span&gt; e w a &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;WriterT&lt;/span&gt; w (&lt;span class=&quot;dt&quot;&gt;Either&lt;/span&gt; e) a&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;isomorphic to &lt;code
class=&quot;sourceCode haskell&quot;&gt;&lt;span class=&quot;dt&quot;&gt;Either&lt;/span&gt; r (a, w)&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;We can already see the difference from the types. In the first case,
the &lt;code&gt;w&lt;/code&gt; is there independently of the value of
&lt;code&gt;Either&lt;/code&gt;. In the second case, if the computation failed, the
whole thing is &lt;code
class=&quot;sourceCode haskell&quot;&gt;&lt;span class=&quot;dt&quot;&gt;Left&lt;/span&gt; msg&lt;/code&gt;, and
we don’t get our log &lt;code&gt;w&lt;/code&gt; back.&lt;/p&gt;
&lt;p&gt;Let’s try the following to confirm our expectations:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb6&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb6-1&quot;&gt;&lt;a href=&quot;#cb6-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;op&quot;&gt;&amp;gt;&lt;/span&gt; runWriter &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; runErrorT &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; tell &lt;span class=&quot;st&quot;&gt;&amp;quot;foo&amp;quot;&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt; throwError &lt;span class=&quot;st&quot;&gt;&amp;quot;err&amp;quot;&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt; tell &lt;span class=&quot;st&quot;&gt;&amp;quot;bar&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-2&quot;&gt;&lt;a href=&quot;#cb6-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;(&lt;span class=&quot;dt&quot;&gt;Left&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;quot;err&amp;quot;&lt;/span&gt;,&lt;span class=&quot;st&quot;&gt;&amp;quot;foo&amp;quot;&lt;/span&gt;)&lt;/span&gt;
&lt;span id=&quot;cb6-3&quot;&gt;&lt;a href=&quot;#cb6-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;op&quot;&gt;&amp;gt;&lt;/span&gt; runErrorT &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; runWriterT &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; tell &lt;span class=&quot;st&quot;&gt;&amp;quot;foo&amp;quot;&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt; throwError &lt;span class=&quot;st&quot;&gt;&amp;quot;err&amp;quot;&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt; tell &lt;span class=&quot;st&quot;&gt;&amp;quot;bar&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb6-4&quot;&gt;&lt;a href=&quot;#cb6-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;dt&quot;&gt;Left&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;quot;err&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;developing-intuition&quot;&gt;Developing intuition&lt;/h2&gt;
&lt;p&gt;When reasoning about a stack of monad transformers, it’s useful to
keep in mind that a transformer knows nothing about its inner monad. It
has to work “inside” that monad. It has no ability to alter or cancel
the effects that happened before in that monad. (It can prevent those
effects from happening, though – see &lt;code
class=&quot;sourceCode haskell&quot;&gt;tell &lt;span class=&quot;st&quot;&gt;&amp;quot;bar&amp;quot;&lt;/span&gt;&lt;/code&gt;
above.)&lt;/p&gt;
&lt;p&gt;In the first example above, which corresponds to &lt;code
class=&quot;sourceCode haskell&quot;&gt;&lt;span class=&quot;dt&quot;&gt;ErrorT&lt;/span&gt; e (&lt;span class=&quot;dt&quot;&gt;Writer&lt;/span&gt; w)&lt;/code&gt;,
the Error monad had to work inside the Writer monad. It simply had no
way to tell the writer monad to “forget” what had been told to it
before.&lt;/p&gt;
&lt;p&gt;In the second example, corresponding to &lt;code
class=&quot;sourceCode haskell&quot;&gt;&lt;span class=&quot;dt&quot;&gt;WriterT&lt;/span&gt; w (&lt;span class=&quot;dt&quot;&gt;Either&lt;/span&gt; e) a&lt;/code&gt;,
the main monad is now &lt;code
class=&quot;sourceCode haskell&quot;&gt;&lt;span class=&quot;dt&quot;&gt;Either&lt;/span&gt; e&lt;/code&gt;. If
it decides to fail, it will return just the error, and nothing else.&lt;/p&gt;
&lt;p&gt;The same logic answers the question why there’s no &lt;code&gt;IOT&lt;/code&gt;,
an IO monad transformer. Imagine this:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb7&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb7-1&quot;&gt;&lt;a href=&quot;#cb7-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb7-2&quot;&gt;&lt;a href=&quot;#cb7-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    targetHit &lt;span class=&quot;ot&quot;&gt;&amp;lt;-&lt;/span&gt; launchMissiles&lt;/span&gt;
&lt;span id=&quot;cb7-3&quot;&gt;&lt;a href=&quot;#cb7-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    when targetHit &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb7-4&quot;&gt;&lt;a href=&quot;#cb7-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;        throwError &lt;span class=&quot;st&quot;&gt;&amp;quot;oops I did it again&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Since &lt;code&gt;throwError&lt;/code&gt; happens in the base monad, the whole
thing is just &lt;code
class=&quot;sourceCode haskell&quot;&gt;&lt;span class=&quot;dt&quot;&gt;Left&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;quot;oops I did it again&amp;quot;&lt;/span&gt;&lt;/code&gt;
– nothing mentions any IO. But what about the missiles?&lt;/p&gt;
&lt;p&gt;If this shallow explanation is not enough to make you comfortable
with transformers, I’d advise to read (or even to write) the
implementation of some standard transformers.&lt;/p&gt;
&lt;h2 id=&quot;even-more-interesting-example-parsec-state&quot;&gt;Even more
interesting example: Parsec + State&lt;/h2&gt;
&lt;p&gt;The Parsec monad already allows us to have &lt;a
href=&quot;http://hackage.haskell.org/packages/archive/parsec/latest/doc/html/Text-Parsec-Prim.html#v:getState&quot;&gt;our
own state&lt;/a&gt;, but let’s see how we can add one independently.&lt;/p&gt;
&lt;p&gt;Again, we have two ways to layer ParsecT and StateT transformers on
top of Identity: &lt;code
class=&quot;sourceCode haskell&quot;&gt;&lt;span class=&quot;dt&quot;&gt;ParsecT&lt;/span&gt; s () (&lt;span class=&quot;dt&quot;&gt;State&lt;/span&gt; u) a&lt;/code&gt;
and &lt;code
class=&quot;sourceCode haskell&quot;&gt;&lt;span class=&quot;dt&quot;&gt;StateT&lt;/span&gt; u (&lt;span class=&quot;dt&quot;&gt;Parsec&lt;/span&gt; s ()) a&lt;/code&gt;.
Is there a difference?&lt;/p&gt;
&lt;p&gt;Recall that Parsec is a backtracking monad. It can execute one
branch, fail, and then execute another branch. Do we observe the state
changes that happened in the aborted branch?&lt;/p&gt;
&lt;p&gt;This will be our test code:&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb8&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb8-1&quot;&gt;&lt;a href=&quot;#cb8-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;((put &lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt; char &lt;span class=&quot;ch&quot;&gt;&amp;#39;b&amp;#39;&lt;/span&gt;) &lt;span class=&quot;op&quot;&gt;&amp;lt;|&amp;gt;&lt;/span&gt; char &lt;span class=&quot;ch&quot;&gt;&amp;#39;a&amp;#39;&lt;/span&gt;) &lt;span class=&quot;op&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt; get&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;We’ll try to run it with the input &lt;code
class=&quot;sourceCode haskell&quot;&gt;&lt;span class=&quot;st&quot;&gt;&amp;quot;a&amp;quot;&lt;/span&gt;&lt;/code&gt;
and initial state &lt;code
class=&quot;sourceCode haskell&quot;&gt;&lt;span class=&quot;dv&quot;&gt;0&lt;/span&gt;&lt;/code&gt;. First,
Parsec executes the left branch of &lt;code
class=&quot;sourceCode haskell&quot;&gt;&lt;span class=&quot;op&quot;&gt;&amp;lt;|&amp;gt;&lt;/span&gt;&lt;/code&gt;,
fails, and proceeds with the right branch. If the state is “global”,
then the final result will be &lt;code
class=&quot;sourceCode haskell&quot;&gt;&lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;&lt;/code&gt;. If the
state is subject to backtracking, then we’ll see &lt;code
class=&quot;sourceCode haskell&quot;&gt;&lt;span class=&quot;dv&quot;&gt;0&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;In the &lt;code
class=&quot;sourceCode haskell&quot;&gt;&lt;span class=&quot;dt&quot;&gt;ParsecT&lt;/span&gt; s () (&lt;span class=&quot;dt&quot;&gt;State&lt;/span&gt; u) a&lt;/code&gt;
case, the base monad is State. ParsecT works inside that monad and
cannot revert the effects that happened there. (It may seem that it
could remember the state of a branch using &lt;code&gt;get&lt;/code&gt; and then
restore it using &lt;code&gt;put&lt;/code&gt;; but a monad transformer has to be
polymorphic in the underlying monad and thus cannot rely on existence of
&lt;code&gt;get&lt;/code&gt; and &lt;code&gt;put&lt;/code&gt;.)&lt;/p&gt;
&lt;p&gt;And indeed, the code&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb9&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb9-1&quot;&gt;&lt;a href=&quot;#cb9-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Text.Parsec&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb9-2&quot;&gt;&lt;a href=&quot;#cb9-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Control.Monad.State&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb9-3&quot;&gt;&lt;a href=&quot;#cb9-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb9-4&quot;&gt;&lt;a href=&quot;#cb9-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;main &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;flip&lt;/span&gt; evalState &lt;span class=&quot;dv&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; runParserT p () &lt;span class=&quot;st&quot;&gt;&amp;quot;-&amp;quot;&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;quot;a&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb9-5&quot;&gt;&lt;a href=&quot;#cb9-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;kw&quot;&gt;where&lt;/span&gt; p &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; ((put &lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt; char &lt;span class=&quot;ch&quot;&gt;&amp;#39;b&amp;#39;&lt;/span&gt;) &lt;span class=&quot;op&quot;&gt;&amp;lt;|&amp;gt;&lt;/span&gt; char &lt;span class=&quot;ch&quot;&gt;&amp;#39;a&amp;#39;&lt;/span&gt;) &lt;span class=&quot;op&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt; get&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;prints &lt;code
class=&quot;sourceCode haskell&quot;&gt;&lt;span class=&quot;dt&quot;&gt;Right&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Let’s now try the second option: layering StateT on top of Parsec. We
cannot use the code above as is, because types do not match: e.g. &lt;code
class=&quot;sourceCode haskell&quot;&gt;char &lt;span class=&quot;ch&quot;&gt;&amp;#39;b&amp;#39;&lt;/span&gt;&lt;/code&gt;
has type &lt;code
class=&quot;sourceCode haskell&quot;&gt;&lt;span class=&quot;dt&quot;&gt;Parsec&lt;/span&gt; s () &lt;span class=&quot;dt&quot;&gt;Char&lt;/span&gt;&lt;/code&gt;,
but we need &lt;code
class=&quot;sourceCode haskell&quot;&gt;&lt;span class=&quot;dt&quot;&gt;StateT&lt;/span&gt; u (&lt;span class=&quot;dt&quot;&gt;Parsec&lt;/span&gt; s ()) &lt;span class=&quot;dt&quot;&gt;Char&lt;/span&gt;&lt;/code&gt;.
Such an upgrade is done by the &lt;code&gt;lift&lt;/code&gt; function.&lt;/p&gt;
&lt;p&gt;Sometimes, however, we need to “downgrade” computations from &lt;code
class=&quot;sourceCode haskell&quot;&gt;&lt;span class=&quot;dt&quot;&gt;StateT&lt;/span&gt; u (&lt;span class=&quot;dt&quot;&gt;Parsec&lt;/span&gt; s ()) a&lt;/code&gt;
to &lt;code
class=&quot;sourceCode haskell&quot;&gt;&lt;span class=&quot;dt&quot;&gt;Parsec&lt;/span&gt; s () a&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;For example, to implement a &lt;code
class=&quot;sourceCode haskell&quot;&gt;&lt;span class=&quot;op&quot;&gt;&amp;lt;|&amp;gt;&lt;/span&gt;&lt;/code&gt;
operator of type&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb10&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb10-1&quot;&gt;&lt;a href=&quot;#cb10-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;ot&quot;&gt;(&amp;lt;|&amp;gt;) ::&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;StateT&lt;/span&gt; u (&lt;span class=&quot;dt&quot;&gt;Parsec&lt;/span&gt; s ()) a &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;StateT&lt;/span&gt; u (&lt;span class=&quot;dt&quot;&gt;Parsec&lt;/span&gt; s ()) a &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;StateT&lt;/span&gt; u (&lt;span class=&quot;dt&quot;&gt;Parsec&lt;/span&gt; s ()) a&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;we need first to downgrade the arguments to plain Parsec computation,
invoke Parsec’s own &lt;code
class=&quot;sourceCode haskell&quot;&gt;&lt;span class=&quot;op&quot;&gt;&amp;lt;|&amp;gt;&lt;/span&gt;&lt;/code&gt; and
then upgrade the result back to StateT.&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot; id=&quot;cb11&quot;&gt;&lt;pre
class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span id=&quot;cb11-1&quot;&gt;&lt;a href=&quot;#cb11-1&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Text.Parsec&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;P&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb11-2&quot;&gt;&lt;a href=&quot;#cb11-2&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kw&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Control.Monad.State&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb11-3&quot;&gt;&lt;a href=&quot;#cb11-3&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb11-4&quot;&gt;&lt;a href=&quot;#cb11-4&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;main &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; runParser (evalStateT p &lt;span class=&quot;dv&quot;&gt;0&lt;/span&gt;) () &lt;span class=&quot;st&quot;&gt;&amp;quot;-&amp;quot;&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;quot;a&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb11-5&quot;&gt;&lt;a href=&quot;#cb11-5&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kw&quot;&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb11-6&quot;&gt;&lt;a href=&quot;#cb11-6&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    p &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; ((put &lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt; char &lt;span class=&quot;ch&quot;&gt;&amp;#39;b&amp;#39;&lt;/span&gt;) &lt;span class=&quot;op&quot;&gt;&amp;lt;|&amp;gt;&lt;/span&gt; char &lt;span class=&quot;ch&quot;&gt;&amp;#39;a&amp;#39;&lt;/span&gt;) &lt;span class=&quot;op&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt; get&lt;/span&gt;
&lt;span id=&quot;cb11-7&quot;&gt;&lt;a href=&quot;#cb11-7&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb11-8&quot;&gt;&lt;a href=&quot;#cb11-8&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    char &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; lift &lt;span class=&quot;op&quot;&gt;.&lt;/span&gt; P.char&lt;/span&gt;
&lt;span id=&quot;cb11-9&quot;&gt;&lt;a href=&quot;#cb11-9&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&quot;cb11-10&quot;&gt;&lt;a href=&quot;#cb11-10&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;    a &lt;span class=&quot;op&quot;&gt;&amp;lt;|&amp;gt;&lt;/span&gt; b &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;StateT&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;$&lt;/span&gt; \s &lt;span class=&quot;ot&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&quot;cb11-11&quot;&gt;&lt;a href=&quot;#cb11-11&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot;&gt;&lt;/a&gt;        runStateT a s &lt;span class=&quot;op&quot;&gt;P.&amp;lt;|&amp;gt;&lt;/span&gt; runStateT b s&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Notice how we explicitly run both branches of &lt;code
class=&quot;sourceCode haskell&quot;&gt;&lt;span class=&quot;op&quot;&gt;&amp;lt;|&amp;gt;&lt;/span&gt;&lt;/code&gt; with
the same state. It’s no surprise now that the state will be
“backtracked” and the result will be &lt;code
class=&quot;sourceCode haskell&quot;&gt;&lt;span class=&quot;dt&quot;&gt;Right&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;0&lt;/span&gt;&lt;/code&gt;.
By the way, this is the same result as would be achieved using Parsec’s
internal state.&lt;/p&gt;
</description>
                        <pubDate>Mon, 02 Jan 2012 20:00:00 +0000</pubDate>
                        <link>http://ro-che.info/articles/2012-01-02-composing-monads</link>
                        <guid isPermaLink="false">http://ro-che.info//articles/2012-01-02-composing-monads.html</guid>
                </item>
        
    </channel> 
</rss>
