-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathatom.xml
More file actions
419 lines (393 loc) · 67.6 KB
/
atom.xml
File metadata and controls
419 lines (393 loc) · 67.6 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<title>joyfulmantis's personal blog</title>
<link href="http://joyfulmantis.github.io/atom.xml" rel="self" />
<link href="http://joyfulmantis.github.io" />
<id>http://joyfulmantis.github.io/atom.xml</id>
<author>
<name>Nathan Maxson</name>
<email>test@example.com</email>
</author>
<updated>2023-12-03T00:00:00Z</updated>
<entry>
<title>RisingTone: A better way to learn Chinese tones</title>
<link href="http://joyfulmantis.github.io/posts/2023-12-03-risingtone.html" />
<id>http://joyfulmantis.github.io/posts/2023-12-03-risingtone.html</id>
<published>2023-12-03T00:00:00Z</published>
<updated>2023-12-03T00:00:00Z</updated>
<summary type="html"><![CDATA[<!-- <div class="info"> -->
<!-- Posted on December 3, 2023 -->
<!-- -->
<!-- </div> -->
<p>TLDR: I have released <a href="https://play.google.com/store/apps/details?id=org.joyfulmantis.risingtone">an app</a> that helps you learn how to differentiate Chinese’s tones. It starts simple with drills that only compare two tones, but later progresses and teaches you to effectively differentiate all the tones in Chinese.</p>
<p>Accents are part of learning a second language as an adult. When we were young and learning our mother tongue, our brains learned how to turn the spectrum of sound that we hear into specific phonemes that convey meaning in our language. Every language turns this spectrum of sound into slightly different phonemes. Thus when German speakers attempts to say “rabbit” in English, they will tend to use the German guttural r <a href="#fn1" class="footnote-ref" id="fnref1" role="doc-noteref"><sup>1</sup></a> to pronounce the “r”, whereas English speakers will use the alveolar approximant. However, while sounding strange to English speakers, such a pronunciation is usually not an impediment to understanding. The guttural r is outside of what we consider a correct r to sound like, but at the same time it is not likely going to get confused with another sound. However, if you use a completely different vowel or consonant what you want to say becomes unclear. “babbit” for example, would not be easily understood as “rabbit”, and “rabbit” and “rub it” are only differentiated by a single vowel.</p>
<p>Chinese is a notorious language to learn for several reasons. Chinese characters are a completely different writing system requiring a significant amount of memorization to master, and there is almost no shared vocabulary with any Indo-European language. It is also intimidating. However, one area of significant difficulty that gets less attention is the tones. Every language has words that are made up of at least a combination of vowels and consonants. Chinese has words that are made up of a combination of vowels, consonants, and tones. Tones in Chinese are effectively a phoneme that most learners have learned to intentionally filter out in their auditory pathways. Learners of Chinese, having grown up never considered the tone of a word as integral to its meaning, can pick up the Chinese set of vowels and consonants just as fast as with any other language, but even learning to differentiate let alone use the Chinese tones, can sometimes feel impossible.</p>
<p>Tones in Chinese tend to be less important than constant and vowels. Music for example is one medium in which tones cannot be realized, but nevertheless their lack does not cause a significant impedance to understanding. Music, however, tends to use vocabulary that is easily understandable with context clues. Speech on everyday subjects is similar in that there is a significantly higher amount of context available to aid in guessing which tone a word should have used. Because of that when the topic is kept simple, someone who is used to foreigners can usually understand what they are attempting to say, even if they do not use tones at all. However, the more advanced the topic, the harder it gets. For Chinese to understand intermediate level speech without the correct tones is significantly harder than for English speakers to understand “rabbit” with the guttural r.</p>
<p>With tones being so crucial to perform at a high level in Chinese, one would imagine that they would be treated with significant importance in CFL (Chinese as a foreign language) education. Unfortunately, that is not the case. Tones tend to be drilled with the rest of the phonetics in the first few lessons, but later seem to get almost no dedicated exposure. Usually only individual tones are drilled, even though as most Chinese words are composed of two syllables and thus two tones. Even if one were to have a thorough grasp of the four tones in isolation, they would be unable to effectively use them in the two syllable words that make up the bulk of Chinese’s vocabulary.</p>
<p>Learning to correctly say Chinese tones is something that would be best learned with a Chinese tutor, however learning to correctly differentiate them can be done with drills. This was the topic of my bachelor’s thesis. To help learners effectively differentiate between them, I created an <a href="https://play.google.com/store/apps/details?id=org.joyfulmantis.risingtone">android app</a> that coaches you on their differences. You start only with two tones, and then successively add more tones to your drills as you progress through the levels. This is something I am also still interested in improving, so if you feel there are areas that can be improved, please hit me up in an email. In addition, the application is open source, so if you have the time, feel free to open a pull request in the repository.</p>
<aside id="footnotes" class="footnotes footnotes-end-of-document" role="doc-endnotes">
<hr />
<ol>
<li id="fn1"><p>Yes, I am aware that this is itself a group of sounds itself. However I was unable to determine which exact guttural r sound most Germans commonly use in this scenario<a href="#fnref1" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
</ol>
</aside>
<div class="comments">
This article is being discussed on <a href="https://news.ycombinator.com/item?id=38509942">Hacker News</a>
</div>
]]></summary>
</entry>
<entry>
<title>Hacking HLS: My Summer of Haskell journey</title>
<link href="http://joyfulmantis.github.io/posts/2023-08-01-hacking-hls.html" />
<id>http://joyfulmantis.github.io/posts/2023-08-01-hacking-hls.html</id>
<published>2023-08-01T00:00:00Z</published>
<updated>2023-08-01T00:00:00Z</updated>
<summary type="html"><![CDATA[<!-- <div class="info"> -->
<!-- Posted on August 1, 2023 -->
<!-- -->
<!-- </div> -->
<p>It’s been almost 6 years since I last posted here. Since then I have finished my bachelors in TCSOL and tried my hand at teaching. Although enjoyable, I could never quite leave the siren call of programming behind me. There is something special about designing and implementing a solution to a problem. Managing a classroom of 40 something tweenagers is special too – but a different kind of special.</p>
<p>Last year I started to brush up my programming skills, and at the beginning of this year I applied to the Summer of Haskell. Previously, Google Summer of Code, which the Summer of Haskell is based off of, was only open to students. However, as of 2022 they now accept any applicant new to open source, so for someone like me who is transitioning to programming it was a perfect fit.</p>
<p>Most projects recommend you start off with making a small change in the codebase before applying to make sure you have the basics down. HLS specifically lists issues that are considered easy, so I picked one for writing a plugin to convert record selectors to record dot syntax. Not knowing any of the codebase, it was a bit of work to understand how things work in HLS land, but with the help of <a href="https://www.tweag.io/blog/2023-01-31-hls-internship-report/">Berk Ozkutuk’s blogpost</a> and his “explicit-records”, I was able to write and ship my plugin.</p>
<figure>
<img src="https://raw.githubusercontent.com/haskell/haskell-language-server/master/plugins/hls-overloaded-record-dot-plugin/example.gif" alt="The overloaded record dot plugin" />
<figcaption aria-hidden="true">The overloaded record dot plugin</figcaption>
</figure>
<p>The project I applied for was implementing resolve support in HLS. Resolve support allows us to delay part of the computational work we need to do to offer code lenses, code actions, and completions to later. Not knowing the difficulty of the project I conservatively estimated I would be able to implement resolve in 6 plugins in addition to general resolve support in core HLS.</p>
<p>Ever since starting working on the codebase in the beginning of June I’ve been busy moving from one PR to the next. It’s been hectic at times, but I am happy to have been able to make more progress than I had expected. Micheal had earlier <a href="https://github.com/haskell/lsp/pull/478">rewritten the haskell lsp-types package</a> to be generated from the specification. That was really a huge boon for anyone implementing any new LSP feature (including for me with my resolve support), since now all the types were already there. However, HLS didn’t support the new package, so <a href="https://github.com/haskell/haskell-language-server/pull/3621">implementing that support</a> was my first task. It was difficult, but also very instructive as I made my way throughout the whole HLS codebase replacing the types that had changed with their new equivalents</p>
<p>I then went and implemented resolve for the <a href="https://github.com/haskell/haskell-language-server/pull/3658">overload-record-dot</a>, <a href="https://github.com/haskell/haskell-language-server/pull/3679">hlint</a> <a href="https://github.com/haskell/haskell-language-server/pull/3682">explicit-imports</a>, and <a href="https://github.com/haskell/haskell-language-server/pull/3729">refine-imports</a> plugins. After that I did some <a href="https://github.com/haskell/haskell-language-server/pull/3688">general refactoring to how resolve is implemented in HLS</a>, giving some nice quality of life improvements, such as always providing the URI to the handler, and decoding the handlers arguments from JSON before passing it to the handler.</p>
<p>What I have worked on most recently is plugin error handling. HLS previously had plugins return a response error that was then sent on to the HLS client. However this approach had some problems. One of them was we usually sent a request to multiple plugins, and if they all returned errors we would just send back a generic error instead of combining them. We also logged everything the same way which was confusing for users and a bit noisy for anyone wanting to debug HLS.</p>
<p><a href="https://github.com/haskell/haskell-language-server/pull/3659">Fendor had done a bunch of work</a> improving how we deal with errors, including some nice ExceptT helper functions that let us fail in predefined ways for some common things we do. As he didn’t have time to finish it, <a href="https://github.com/haskell/haskell-language-server/pull/3717">I took it on</a> and then implemented the PluginError type through the core HLS plugin handling code. With that change, it is now much easier for plugins to provide more discrete errors, which then allows us to choose which error to return to the client based on severity, and log serious errors in plugins differently from failures due to parse errors in the user code among other benefits.</p>
<p>While implementing these features I have also had the opportunity to fix some bugs I have encountered along the way, like <a href="https://github.com/haskell/haskell-language-server/pull/3674">fixing the pragma plugin causing incorrect code actions</a>, and <a href="https://github.com/haskell/haskell-language-server/pull/3696">keeping exceptions in commands from taking down the whole server</a>.</p>
<p>My Summer of Haskell is only a bit more than halfway through, so I hope to keep hacking on the codebase, adding resolve support to more plugins, squashing more bugs, and finding other ways I can improve the codebase. For giving me this opportunity to spend my summer working on HLS I would like to thank my mentor Micheal, the HLS team, the Haskell Foundation, and everyone else who has contributed to the Haskell community.</p>
]]></summary>
</entry>
<entry>
<title>Functors, Applicatives, and Monads: You don't need to know theory to use them</title>
<link href="http://joyfulmantis.github.io/posts/2017-08-23-functors-applicatives-monads.html" />
<id>http://joyfulmantis.github.io/posts/2017-08-23-functors-applicatives-monads.html</id>
<published>2017-08-23T00:00:00Z</published>
<updated>2017-08-23T00:00:00Z</updated>
<summary type="html"><![CDATA[<!-- <div class="info"> -->
<!-- Posted on August 23, 2017 -->
<!-- -->
<!-- </div> -->
<div class="edit_history">
EDIT: Changed some wording to clarify that a typeclass should never be thought of as a container. See this post's <a href="https://github.com/joyfulmantis/joyfulmantis.github.io/commits/master/posts/2017-08-23-functors-applicatives-monads.html">commit history</a> for more details.
</div>
<p>Figuring out how to use the common functional programming typeclassess is not as hard as you would think. The key here is not to start with understanding the category theory behind them, but rather first start with using their implementations in the standard datatypes. Eventually by using them throughout different datatypes you will be able to grasp the larger picture, without having to touch the slightest bit of category theory.</p>
<p>What datatypes that implement any of Functors, Applicatives or Monads have in common is that they all have some data, usually polymorphic (aka it really could be <strong>any</strong> type of data) locked inside, and that data can’t be naively accessed. Functors, Applicatives, and Monads each define certain specific ways that that data can be accessed. Throughout this article I will use standard datatypes that are easy to reason about, and show how their implementations of the aforementioned three typeclasses pan out.</p>
<p>One easy to reason about datatype in Haskell is the datatype <code class="sourceCode haskell"><span class="dt">Maybe</span> a</code>, in this case specified to be <code class="sourceCode haskell"><span class="dt">Maybe</span> <span class="dt">String</span></code>. This datatype can either be constructed as <code class="sourceCode haskell"><span class="dt">Just</span> <span class="dt">String</span></code>, which is simply a wrapper around a string or <code class="sourceCode haskell"><span class="dt">Nothing</span></code>, which doesn’t hold any value at all. With this in mind you can see that if we receive a <code class="sourceCode haskell"><span class="dt">Maybe</span> <span class="dt">String</span></code> with no guarantees on whether or not it actually contains a string or not, there is no simple way to access the enclosed string. For example suppose there was a function</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="ot">getInnerString ::</span> <span class="dt">Maybe</span> <span class="dt">String</span> <span class="ot">-></span> <span class="dt">String</span></span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a>getInnerString (<span class="dt">Just</span> string) <span class="ot">=</span> string</span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a>getInnerString (<span class="dt">Nothing</span>) <span class="ot">=</span> <span class="fu">error</span> <span class="st">"system blowing up, activating emergency protocols..."</span></span></code></pre></div>
<p>and we gave it a <code class="sourceCode haskell"><span class="dt">Nothing</span></code>. In that case it would only have the option of crashing the program (with an error), and that is something we do not want to do.</p>
<p>The most basic typeclass available to us is the Functor, and it provides us with the ability to apply a function to the value inside the datatype that implements the Functor without worrying about whether or not it is possible to unwrap it. The important function that is required to implement the Functor typeclass is</p>
<div class="sourceCode" id="cb2"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="ot">(<$>) ::</span> <span class="dt">Functor</span> f <span class="ot">=></span> (a <span class="ot">-></span> b) <span class="ot">-></span> f a <span class="ot">-></span> f b</span></code></pre></div>
<p>This may seem confusing, especially since haskellers like to use these sorts of symbol functions between the two arguments that they are applying to it, but specifying it to <code class="sourceCode haskell"><span class="dt">Maybe</span> <span class="dt">String</span></code> and renaming it to something pronounceable already helps to remove almost all of the confusion</p>
<div class="sourceCode" id="cb3"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="fu">map</span><span class="ot"> ::</span> (<span class="dt">String</span> <span class="ot">-></span> b) <span class="ot">-></span> <span class="dt">Maybe</span> <span class="dt">String</span> <span class="ot">-></span> <span class="dt">Maybe</span> b</span></code></pre></div>
<p>Here instead of unwrapping Maybe and then applying a function to the unwrapped value, we instead provide Maybe with the function that we want to apply, and let it take care of the rest. One result of having Maybe apply the value is that the resulting value has never gotten unwrapped, and therefore we need not worry about wrapping it up again.</p>
<p>Here are some examples of how this plays out</p>
<div class="sourceCode" id="cb4"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a>mapF <span class="ot">=</span> (<span class="op"><$></span>)</span>
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb4-3"><a href="#cb4-3" aria-hidden="true" tabindex="-1"></a><span class="ot">smellsBadF ::</span> <span class="dt">String</span> <span class="ot">-></span> <span class="dt">String</span></span>
<span id="cb4-4"><a href="#cb4-4" aria-hidden="true" tabindex="-1"></a>smellsBadF who <span class="ot">=</span> who <span class="op">++</span> <span class="st">" smells awful"</span></span>
<span id="cb4-5"><a href="#cb4-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb4-6"><a href="#cb4-6" aria-hidden="true" tabindex="-1"></a><span class="ot">maybeJamesF ::</span> <span class="dt">Maybe</span> <span class="dt">String</span></span>
<span id="cb4-7"><a href="#cb4-7" aria-hidden="true" tabindex="-1"></a>maybeJamesF <span class="ot">=</span> <span class="dt">Just</span> <span class="st">"James"</span></span>
<span id="cb4-8"><a href="#cb4-8" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb4-9"><a href="#cb4-9" aria-hidden="true" tabindex="-1"></a><span class="ot">maybeJohnF ::</span> <span class="dt">Maybe</span> <span class="dt">String</span></span>
<span id="cb4-10"><a href="#cb4-10" aria-hidden="true" tabindex="-1"></a>maybeJohnF <span class="ot">=</span> <span class="dt">Nothing</span></span>
<span id="cb4-11"><a href="#cb4-11" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb4-12"><a href="#cb4-12" aria-hidden="true" tabindex="-1"></a><span class="ot">maybeStinkyJamesF ::</span> <span class="dt">Maybe</span> <span class="dt">String</span></span>
<span id="cb4-13"><a href="#cb4-13" aria-hidden="true" tabindex="-1"></a>maybeStinkyJamesF <span class="ot">=</span> mapF smellsBadF maybeJamesF</span>
<span id="cb4-14"><a href="#cb4-14" aria-hidden="true" tabindex="-1"></a><span class="co">-- > maybeStinkyJamesF </span></span>
<span id="cb4-15"><a href="#cb4-15" aria-hidden="true" tabindex="-1"></a><span class="co">-- Just "James smells awful"</span></span>
<span id="cb4-16"><a href="#cb4-16" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb4-17"><a href="#cb4-17" aria-hidden="true" tabindex="-1"></a><span class="ot">maybeStinkyJohnF ::</span> <span class="dt">Maybe</span> <span class="dt">String</span></span>
<span id="cb4-18"><a href="#cb4-18" aria-hidden="true" tabindex="-1"></a>maybeStinkyJohnF <span class="ot">=</span> mapF smellsBadF maybeJohnF</span>
<span id="cb4-19"><a href="#cb4-19" aria-hidden="true" tabindex="-1"></a><span class="co">-- > maybeStinkyJohnF</span></span>
<span id="cb4-20"><a href="#cb4-20" aria-hidden="true" tabindex="-1"></a><span class="co">-- Nothing</span></span></code></pre></div>
<p>You may have used this even if you have never seen a ‘functional language’ before. It is exactly the same as the map function several languages use over a linked list. If you think of it, it makes sense that linked lists also implements the Functor typeclass. After all it is also a container that includes data, but whose data is also not easily accessible. For example, even if we assume the head of the list is all the so contained data, we can’t even be sure that the list we are getting has a head, or instead is an empty list</p>
<div class="sourceCode" id="cb5"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a>mapF <span class="ot">=</span> (<span class="op"><$></span>)</span>
<span id="cb5-2"><a href="#cb5-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb5-3"><a href="#cb5-3" aria-hidden="true" tabindex="-1"></a><span class="ot">smellsBadF ::</span> <span class="dt">String</span> <span class="ot">-></span> <span class="dt">String</span></span>
<span id="cb5-4"><a href="#cb5-4" aria-hidden="true" tabindex="-1"></a>smellsBadF who <span class="ot">=</span> who <span class="op">++</span> <span class="st">" smells awful"</span></span>
<span id="cb5-5"><a href="#cb5-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb5-6"><a href="#cb5-6" aria-hidden="true" tabindex="-1"></a><span class="ot">peopleF ::</span> [<span class="dt">String</span>]</span>
<span id="cb5-7"><a href="#cb5-7" aria-hidden="true" tabindex="-1"></a>peopleF <span class="ot">=</span> [<span class="st">"Fred"</span>, <span class="st">"Sandra"</span>, <span class="st">"Bill"</span>]</span>
<span id="cb5-8"><a href="#cb5-8" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb5-9"><a href="#cb5-9" aria-hidden="true" tabindex="-1"></a><span class="ot">ghostsF ::</span> [<span class="dt">String</span>]</span>
<span id="cb5-10"><a href="#cb5-10" aria-hidden="true" tabindex="-1"></a>ghostsF <span class="ot">=</span> []</span>
<span id="cb5-11"><a href="#cb5-11" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb5-12"><a href="#cb5-12" aria-hidden="true" tabindex="-1"></a><span class="ot">stinkyPeopleF ::</span> [<span class="dt">String</span>]</span>
<span id="cb5-13"><a href="#cb5-13" aria-hidden="true" tabindex="-1"></a>stinkyPeopleF <span class="ot">=</span> mapF smellsBadF peopleF</span>
<span id="cb5-14"><a href="#cb5-14" aria-hidden="true" tabindex="-1"></a><span class="co">-- > stinkyPeopleF</span></span>
<span id="cb5-15"><a href="#cb5-15" aria-hidden="true" tabindex="-1"></a><span class="co">-- ["Fred smells awful", "Sandra smells awful", "Bill smells awful"]</span></span>
<span id="cb5-16"><a href="#cb5-16" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb5-17"><a href="#cb5-17" aria-hidden="true" tabindex="-1"></a><span class="ot">stinkyGhostsF ::</span> [<span class="dt">String</span>]</span>
<span id="cb5-18"><a href="#cb5-18" aria-hidden="true" tabindex="-1"></a>stinkyGhostsF <span class="ot">=</span> mapF smellsBadF ghostsF</span>
<span id="cb5-19"><a href="#cb5-19" aria-hidden="true" tabindex="-1"></a><span class="co">-- > stinkyGhostsF</span></span>
<span id="cb5-20"><a href="#cb5-20" aria-hidden="true" tabindex="-1"></a><span class="co">-- []</span></span></code></pre></div>
<p>Above using the Functor typeclass, we have discovered that even though it has a scary name, it’s bark is certainly bigger than it’s bite. We shall find below that learning the Functor typeclass was not a singular exception, but rather a general rule.</p>
<p>The next typeclass we shall tackle is the Applicative typeclass. Again any datatypes that implement the Applicative typeclass usually contains enclosed data that is hard to easily access. Another thing to keep in mind, is that any datatype that implements the Applicative typeclass also implements the Functor typeclass. The two functions that are required to implement the Applicative typeclass are</p>
<div class="sourceCode" id="cb6"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a><span class="fu">pure</span><span class="ot"> ::</span> <span class="dt">Applicative</span> f <span class="ot">=></span> a <span class="ot">-></span> f a</span>
<span id="cb6-2"><a href="#cb6-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb6-3"><a href="#cb6-3" aria-hidden="true" tabindex="-1"></a><span class="co">--and</span></span>
<span id="cb6-4"><a href="#cb6-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb6-5"><a href="#cb6-5" aria-hidden="true" tabindex="-1"></a><span class="ot">(<*>) ::</span> <span class="dt">Applicative</span> f <span class="ot">=></span> f (a <span class="ot">-></span> b) <span class="ot">-></span> f a <span class="ot">-></span> f b</span></code></pre></div>
<p>Again this looks more complicated then it really is, but that’s just because it is using symbols and is generic across all datatypes that implement the Applicative typeclass. If we specify to <code class="sourceCode haskell"><span class="dt">Maybe</span> <span class="dt">String</span></code> and change the function names, it quickly becomes much easier to reason about.</p>
<div class="sourceCode" id="cb7"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true" tabindex="-1"></a><span class="ot">wrap ::</span> a <span class="ot">-></span> <span class="dt">Mabye</span> a</span>
<span id="cb7-2"><a href="#cb7-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb7-3"><a href="#cb7-3" aria-hidden="true" tabindex="-1"></a><span class="ot">apply ::</span> <span class="dt">Maybe</span> (<span class="dt">String</span> <span class="ot">-></span> b) <span class="ot">-></span> <span class="dt">Maybe</span> <span class="dt">String</span> <span class="ot">-></span> <span class="dt">Maybe</span> b</span></code></pre></div>
<p>For the wrap function there is really almost nothing to it. It takes a value and encloses it in the datatype that implements the Applicative typeclass. For example looking back at our maybeJames function from above we can change it just so</p>
<div class="sourceCode" id="cb8"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb8-1"><a href="#cb8-1" aria-hidden="true" tabindex="-1"></a>wrapA <span class="ot">=</span> <span class="fu">pure</span></span>
<span id="cb8-2"><a href="#cb8-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb8-3"><a href="#cb8-3" aria-hidden="true" tabindex="-1"></a><span class="co">-- the orginal function</span></span>
<span id="cb8-4"><a href="#cb8-4" aria-hidden="true" tabindex="-1"></a><span class="ot">maybeJamesF ::</span> <span class="dt">Maybe</span> <span class="dt">String</span></span>
<span id="cb8-5"><a href="#cb8-5" aria-hidden="true" tabindex="-1"></a>maybeJamesF <span class="ot">=</span> <span class="dt">Just</span> <span class="st">"James"</span></span>
<span id="cb8-6"><a href="#cb8-6" aria-hidden="true" tabindex="-1"></a><span class="co">-- > maybeJamesF</span></span>
<span id="cb8-7"><a href="#cb8-7" aria-hidden="true" tabindex="-1"></a><span class="co">-- Just "James"</span></span>
<span id="cb8-8"><a href="#cb8-8" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb8-9"><a href="#cb8-9" aria-hidden="true" tabindex="-1"></a><span class="co">-- and now using the Applicative typeclass</span></span>
<span id="cb8-10"><a href="#cb8-10" aria-hidden="true" tabindex="-1"></a><span class="ot">maybeJamesA ::</span> <span class="dt">Maybe</span> <span class="dt">String</span></span>
<span id="cb8-11"><a href="#cb8-11" aria-hidden="true" tabindex="-1"></a>maybeJamesA <span class="ot">=</span> wrapA <span class="st">"James"</span></span>
<span id="cb8-12"><a href="#cb8-12" aria-hidden="true" tabindex="-1"></a><span class="co">-- > maybeJamesF</span></span>
<span id="cb8-13"><a href="#cb8-13" aria-hidden="true" tabindex="-1"></a><span class="co">-- Just "James"</span></span>
<span id="cb8-14"><a href="#cb8-14" aria-hidden="true" tabindex="-1"></a><span class="co">-- > maybeJamesA == maybeJamesF</span></span>
<span id="cb8-15"><a href="#cb8-15" aria-hidden="true" tabindex="-1"></a><span class="co">-- True</span></span></code></pre></div>
<p>The apply function is equally easy to wrap your mind around. It is also much more powerful than the mapping function from before, because whereas the map function can only apply a function to operate on the datatype’s inner value, the apply function (paired with the wrap function) can not only be used the same way, but can also be used to compose multiple wrapped values together. To see this in action we will first take the example that we worked on with the Functor typeclass and use functions from the Applicative typeclass instead.</p>
<div class="sourceCode" id="cb9"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb9-1"><a href="#cb9-1" aria-hidden="true" tabindex="-1"></a>wrapA <span class="ot">=</span> <span class="fu">pure</span></span>
<span id="cb9-2"><a href="#cb9-2" aria-hidden="true" tabindex="-1"></a>applyA <span class="ot">=</span> (<span class="op"><*></span>)</span>
<span id="cb9-3"><a href="#cb9-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-4"><a href="#cb9-4" aria-hidden="true" tabindex="-1"></a><span class="ot">smellsBadA ::</span> <span class="dt">String</span> <span class="ot">-></span> <span class="dt">String</span></span>
<span id="cb9-5"><a href="#cb9-5" aria-hidden="true" tabindex="-1"></a>smellsBadA who <span class="ot">=</span> who <span class="op">++</span> <span class="st">" smells awful"</span></span>
<span id="cb9-6"><a href="#cb9-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-7"><a href="#cb9-7" aria-hidden="true" tabindex="-1"></a><span class="ot">maybeSmellsBadA ::</span> <span class="dt">Maybe</span> (<span class="dt">String</span> <span class="ot">-></span> <span class="dt">String</span>)</span>
<span id="cb9-8"><a href="#cb9-8" aria-hidden="true" tabindex="-1"></a>maybeSmellsBadA <span class="ot">=</span> wrapA smellsBadA</span>
<span id="cb9-9"><a href="#cb9-9" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-10"><a href="#cb9-10" aria-hidden="true" tabindex="-1"></a><span class="ot">maybeJamesA ::</span> <span class="dt">Maybe</span> <span class="dt">String</span></span>
<span id="cb9-11"><a href="#cb9-11" aria-hidden="true" tabindex="-1"></a>maybeJamesA <span class="ot">=</span> wrapA <span class="st">"James"</span></span>
<span id="cb9-12"><a href="#cb9-12" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-13"><a href="#cb9-13" aria-hidden="true" tabindex="-1"></a><span class="ot">maybeJohnA ::</span> <span class="dt">Maybe</span> <span class="dt">String</span></span>
<span id="cb9-14"><a href="#cb9-14" aria-hidden="true" tabindex="-1"></a>maybeJohnA <span class="ot">=</span> <span class="dt">Nothing</span></span>
<span id="cb9-15"><a href="#cb9-15" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-16"><a href="#cb9-16" aria-hidden="true" tabindex="-1"></a><span class="ot">maybeStinkyJamesA ::</span> <span class="dt">Maybe</span> <span class="dt">String</span></span>
<span id="cb9-17"><a href="#cb9-17" aria-hidden="true" tabindex="-1"></a>maybeStinkyJamesA <span class="ot">=</span> applyA maybeSmellsBadA maybeJamesA</span>
<span id="cb9-18"><a href="#cb9-18" aria-hidden="true" tabindex="-1"></a><span class="co">-- > maybeStinkyJamesA</span></span>
<span id="cb9-19"><a href="#cb9-19" aria-hidden="true" tabindex="-1"></a><span class="co">-- Just "James smells awful"</span></span>
<span id="cb9-20"><a href="#cb9-20" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-21"><a href="#cb9-21" aria-hidden="true" tabindex="-1"></a><span class="ot">maybeStinkyJohnA ::</span> <span class="dt">Maybe</span> <span class="dt">String</span></span>
<span id="cb9-22"><a href="#cb9-22" aria-hidden="true" tabindex="-1"></a>maybeStinkyJohnA <span class="ot">=</span> applyA maybeSmellsBadA maybeJohnA</span>
<span id="cb9-23"><a href="#cb9-23" aria-hidden="true" tabindex="-1"></a><span class="co">-- > maybeStinkyJohnA</span></span>
<span id="cb9-24"><a href="#cb9-24" aria-hidden="true" tabindex="-1"></a><span class="co">-- Nothing</span></span></code></pre></div>
<p>And then we will spice it up a little by still using some of the function from above, but now also using the apply function to compose two Maybe values.</p>
<div class="sourceCode" id="cb10"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb10-1"><a href="#cb10-1" aria-hidden="true" tabindex="-1"></a>wrapA <span class="ot">=</span> <span class="fu">pure</span></span>
<span id="cb10-2"><a href="#cb10-2" aria-hidden="true" tabindex="-1"></a>applyA <span class="ot">=</span> (<span class="op"><*></span>)</span>
<span id="cb10-3"><a href="#cb10-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb10-4"><a href="#cb10-4" aria-hidden="true" tabindex="-1"></a><span class="ot">smellsBadA ::</span> <span class="dt">String</span> <span class="ot">-></span> <span class="dt">String</span></span>
<span id="cb10-5"><a href="#cb10-5" aria-hidden="true" tabindex="-1"></a>smellsBadA who <span class="ot">=</span> who <span class="op">++</span> <span class="st">" smells awful"</span></span>
<span id="cb10-6"><a href="#cb10-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb10-7"><a href="#cb10-7" aria-hidden="true" tabindex="-1"></a><span class="ot">maybeFredA ::</span> <span class="dt">Maybe</span> <span class="dt">String</span></span>
<span id="cb10-8"><a href="#cb10-8" aria-hidden="true" tabindex="-1"></a>maybeFredA <span class="ot">=</span> wrapA <span class="st">"Fred"</span></span>
<span id="cb10-9"><a href="#cb10-9" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb10-10"><a href="#cb10-10" aria-hidden="true" tabindex="-1"></a><span class="ot">maybeJamesA ::</span> <span class="dt">Maybe</span> <span class="dt">String</span></span>
<span id="cb10-11"><a href="#cb10-11" aria-hidden="true" tabindex="-1"></a>maybeJamesA <span class="ot">=</span> wrapA <span class="st">"James"</span></span>
<span id="cb10-12"><a href="#cb10-12" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb10-13"><a href="#cb10-13" aria-hidden="true" tabindex="-1"></a><span class="ot">maybeJohnA ::</span> <span class="dt">Maybe</span> <span class="dt">String</span></span>
<span id="cb10-14"><a href="#cb10-14" aria-hidden="true" tabindex="-1"></a>maybeJohnA <span class="ot">=</span> <span class="dt">Nothing</span></span>
<span id="cb10-15"><a href="#cb10-15" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb10-16"><a href="#cb10-16" aria-hidden="true" tabindex="-1"></a><span class="ot">bothSmellBadA ::</span> <span class="dt">String</span> <span class="ot">-></span> <span class="dt">String</span> <span class="ot">-></span> <span class="dt">String</span></span>
<span id="cb10-17"><a href="#cb10-17" aria-hidden="true" tabindex="-1"></a>bothSmellBadA who1 who2 <span class="ot">=</span> </span>
<span id="cb10-18"><a href="#cb10-18" aria-hidden="true" tabindex="-1"></a> (smellsBadA who1) <span class="op">++</span> <span class="st">", but "</span> <span class="op">++</span> (smellsBadA who2) <span class="op">++</span> <span class="st">" too!"</span></span>
<span id="cb10-19"><a href="#cb10-19" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb10-20"><a href="#cb10-20" aria-hidden="true" tabindex="-1"></a><span class="ot">maybeBothSmellBadA ::</span> <span class="dt">Maybe</span> (<span class="dt">String</span> <span class="ot">-></span> <span class="dt">String</span> <span class="ot">-></span> <span class="dt">String</span>)</span>
<span id="cb10-21"><a href="#cb10-21" aria-hidden="true" tabindex="-1"></a>maybeBothSmellBadA <span class="ot">=</span> wrapA bothSmellBadA</span>
<span id="cb10-22"><a href="#cb10-22" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb10-23"><a href="#cb10-23" aria-hidden="true" tabindex="-1"></a><span class="ot">maybeJamesFredBothSmellA ::</span> <span class="dt">Maybe</span> <span class="dt">String</span></span>
<span id="cb10-24"><a href="#cb10-24" aria-hidden="true" tabindex="-1"></a>maybeJamesFredBothSmellA <span class="ot">=</span> applyA (applyA maybeBothSmellBadA maybeJamesA) maybeFredA</span>
<span id="cb10-25"><a href="#cb10-25" aria-hidden="true" tabindex="-1"></a><span class="co">-- > maybeJamesFredBothSmellA</span></span>
<span id="cb10-26"><a href="#cb10-26" aria-hidden="true" tabindex="-1"></a><span class="co">-- Just "James smells awful, but Fred smells awful too!"</span></span>
<span id="cb10-27"><a href="#cb10-27" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb10-28"><a href="#cb10-28" aria-hidden="true" tabindex="-1"></a><span class="ot">maybeJamesJohnBothSmellA ::</span> <span class="dt">Maybe</span> <span class="dt">String</span></span>
<span id="cb10-29"><a href="#cb10-29" aria-hidden="true" tabindex="-1"></a>maybeJamesJohnBothSmellA <span class="ot">=</span> applyA (applyA maybeBothSmellBadA maybeJamesA) maybeJohnA</span>
<span id="cb10-30"><a href="#cb10-30" aria-hidden="true" tabindex="-1"></a><span class="co">-- > maybeJamesJohnBothSmellA</span></span>
<span id="cb10-31"><a href="#cb10-31" aria-hidden="true" tabindex="-1"></a><span class="co">-- Nothing</span></span></code></pre></div>
<p>How come we can apply only one wrapped function to two different wrapped values? The key here is that Haskell uses currying, so a function that takes two arguments, is in fact the same as a function that takes one argument and returns as a a value another function that also takes a value and then that finally returns the actual result. To see it in types</p>
<div class="sourceCode" id="cb11"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb11-1"><a href="#cb11-1" aria-hidden="true" tabindex="-1"></a><span class="ot">maybeBothSmellBadA ::</span> <span class="dt">Maybe</span> (<span class="dt">String</span> <span class="ot">-></span> (<span class="dt">String</span> <span class="ot">-></span> <span class="dt">String</span>))</span>
<span id="cb11-2"><a href="#cb11-2" aria-hidden="true" tabindex="-1"></a><span class="co">-- this is the same as Maybe (String -> String -> String) but the parens are</span></span>
<span id="cb11-3"><a href="#cb11-3" aria-hidden="true" tabindex="-1"></a><span class="co">-- added to increase understanding</span></span>
<span id="cb11-4"><a href="#cb11-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb11-5"><a href="#cb11-5" aria-hidden="true" tabindex="-1"></a><span class="ot">applyA1st ::</span> <span class="dt">Maybe</span> (<span class="dt">String</span> <span class="ot">-></span> (<span class="dt">String</span> <span class="ot">-></span> <span class="dt">String</span>)) <span class="ot">-></span> <span class="dt">Maybe</span> <span class="dt">String</span> <span class="ot">-></span> <span class="dt">Maybe</span> (<span class="dt">String</span> <span class="ot">-></span> <span class="dt">String</span>)</span>
<span id="cb11-6"><a href="#cb11-6" aria-hidden="true" tabindex="-1"></a>applyA1st <span class="ot">=</span> applyA</span>
<span id="cb11-7"><a href="#cb11-7" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb11-8"><a href="#cb11-8" aria-hidden="true" tabindex="-1"></a><span class="ot">maybeJamesFredBothSmellA1st ::</span> <span class="dt">Maybe</span> (<span class="dt">String</span> <span class="ot">-></span> <span class="dt">String</span>)</span>
<span id="cb11-9"><a href="#cb11-9" aria-hidden="true" tabindex="-1"></a>maybeJamesFredBothSmellA1st <span class="ot">=</span> apply1st maybeBothSmellBadA maybeJamesA</span>
<span id="cb11-10"><a href="#cb11-10" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb11-11"><a href="#cb11-11" aria-hidden="true" tabindex="-1"></a><span class="ot">applyA2cnd ::</span> <span class="dt">Maybe</span> (<span class="dt">String</span> <span class="ot">-></span> <span class="dt">String</span>) <span class="ot">-></span> <span class="dt">Maybe</span> <span class="dt">String</span> <span class="ot">-></span> <span class="dt">Maybe</span> <span class="dt">String</span></span>
<span id="cb11-12"><a href="#cb11-12" aria-hidden="true" tabindex="-1"></a>applyA2cnd <span class="ot">=</span> applyA</span>
<span id="cb11-13"><a href="#cb11-13" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb11-14"><a href="#cb11-14" aria-hidden="true" tabindex="-1"></a><span class="ot">maybeJamesFredBothSmellA2cnd ::</span> <span class="dt">Maybe</span> <span class="dt">String</span></span>
<span id="cb11-15"><a href="#cb11-15" aria-hidden="true" tabindex="-1"></a>maybeJamesFredBothSmellA2cnd <span class="ot">=</span> apply2cnd maybeJamesFredBothSmell1st maybeFredA</span></code></pre></div>
<p>Another way to see the power of Applicative’s apply function is to use <code class="sourceCode haskell"><span class="dt">Control.Monad.Writer</span></code>. It is a datatype that allows us to have a value that comes with an accompanying log. When the writer’s are composed, the logs are composed (by appending) for free too.</p>
<div class="sourceCode" id="cb12"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb12-1"><a href="#cb12-1" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span> <span class="dt">Control.Monad.Writer</span></span>
<span id="cb12-2"><a href="#cb12-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb12-3"><a href="#cb12-3" aria-hidden="true" tabindex="-1"></a>applyA <span class="ot">=</span> (<span class="op"><*></span>)</span>
<span id="cb12-4"><a href="#cb12-4" aria-hidden="true" tabindex="-1"></a>wrapA <span class="ot">=</span> <span class="fu">pure</span></span>
<span id="cb12-5"><a href="#cb12-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb12-6"><a href="#cb12-6" aria-hidden="true" tabindex="-1"></a><span class="ot">jamesWriterA ::</span> <span class="dt">Writer</span> [<span class="dt">String</span>] <span class="dt">String</span></span>
<span id="cb12-7"><a href="#cb12-7" aria-hidden="true" tabindex="-1"></a>jamesWriterA <span class="ot">=</span> writer (<span class="st">"James"</span>, [<span class="st">"Creating Person: James"</span>])</span>
<span id="cb12-8"><a href="#cb12-8" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb12-9"><a href="#cb12-9" aria-hidden="true" tabindex="-1"></a><span class="ot">fredWriterA ::</span> <span class="dt">Writer</span> [<span class="dt">String</span>] <span class="dt">String</span></span>
<span id="cb12-10"><a href="#cb12-10" aria-hidden="true" tabindex="-1"></a>fredWriterA <span class="ot">=</span> writer (<span class="st">"Fred"</span>, [<span class="st">"Creating Person: Fred"</span>])</span>
<span id="cb12-11"><a href="#cb12-11" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb12-12"><a href="#cb12-12" aria-hidden="true" tabindex="-1"></a><span class="ot">theyHateA ::</span> <span class="dt">String</span> <span class="ot">-></span> <span class="dt">String</span> <span class="ot">-></span> <span class="dt">String</span></span>
<span id="cb12-13"><a href="#cb12-13" aria-hidden="true" tabindex="-1"></a>theyHateA person1 person2 <span class="ot">=</span> person1 <span class="op">++</span> <span class="st">" hates "</span> <span class="op">++</span> person2</span>
<span id="cb12-14"><a href="#cb12-14" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb12-15"><a href="#cb12-15" aria-hidden="true" tabindex="-1"></a><span class="ot">theyHateWriterA ::</span> <span class="dt">Writer</span> [<span class="dt">String</span>] (<span class="dt">String</span> <span class="ot">-></span> <span class="dt">String</span> <span class="ot">-></span> <span class="dt">String</span>)</span>
<span id="cb12-16"><a href="#cb12-16" aria-hidden="true" tabindex="-1"></a>theyHateWriterA <span class="ot">=</span> wrapA theyHateA</span>
<span id="cb12-17"><a href="#cb12-17" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb12-18"><a href="#cb12-18" aria-hidden="true" tabindex="-1"></a><span class="ot">jamesHatesFredWriterA ::</span> <span class="dt">Writer</span> [<span class="dt">String</span>] <span class="dt">String</span></span>
<span id="cb12-19"><a href="#cb12-19" aria-hidden="true" tabindex="-1"></a>jamesHatesFredWriterA <span class="ot">=</span> applyA (applyA theyHateWriterA jamesWriterA) fredWriterA</span>
<span id="cb12-20"><a href="#cb12-20" aria-hidden="true" tabindex="-1"></a><span class="co">-- > runWriter jamesHatesFredWriterA</span></span>
<span id="cb12-21"><a href="#cb12-21" aria-hidden="true" tabindex="-1"></a><span class="co">-- ("James hates Fred",["Creating Person: James","Creating Person: Fred"])</span></span></code></pre></div>
<p>And that’s already most of it. The final typeclass we want to talk about is the “dreaded” Monad. But just as the Applicative and Functor typeclasses are not that hard, the Monad typeclass is not substantively harder to understand than they were either. Just like all datatypes that implement the Applicative typeclass also implement the Functor typeclass, so all datatypes that implement the Monad typeclass also implement the Applicative typeclass (and therefore the Functor typeclass too).</p>
<p>There is only one<a href="#fn1" class="footnote-ref" id="fnref1" role="doc-noteref"><sup>1</sup></a> new function that needs to be declared to implement the Monad typeclass.</p>
<div class="sourceCode" id="cb13"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb13-1"><a href="#cb13-1" aria-hidden="true" tabindex="-1"></a><span class="ot">(=<<) ::</span> <span class="dt">Monad</span> m <span class="ot">=></span> (a <span class="ot">-></span> m b) <span class="ot">-></span> m a <span class="ot">-></span> m b</span></code></pre></div>
<p>Again, scarier than it actually is, since it’s all symbols, and is generic for any Monad. Desymbolizing it, specifying it for <code class="sourceCode haskell"><span class="dt">Maybe</span> <span class="dt">String</span></code> and giving it a pronounceable name gives us</p>
<div class="sourceCode" id="cb14"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb14-1"><a href="#cb14-1" aria-hidden="true" tabindex="-1"></a><span class="ot">bind ::</span> (<span class="dt">String</span> <span class="ot">-></span> <span class="dt">Maybe</span> b) <span class="ot">-></span> <span class="dt">Mabye</span> <span class="dt">String</span> <span class="ot">-></span> <span class="dt">Maybe</span> b</span></code></pre></div>
<p>Re-implementing what we just did with Functor and then Applicative in Monad is not too hard to manage.</p>
<div class="sourceCode" id="cb15"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb15-1"><a href="#cb15-1" aria-hidden="true" tabindex="-1"></a>wrapM <span class="ot">=</span> <span class="fu">return</span> </span>
<span id="cb15-2"><a href="#cb15-2" aria-hidden="true" tabindex="-1"></a><span class="co">-- pure in the Applicative typeclass is called return, groovy right?</span></span>
<span id="cb15-3"><a href="#cb15-3" aria-hidden="true" tabindex="-1"></a>bindM <span class="ot">=</span> (<span class="op">=<<</span>)</span>
<span id="cb15-4"><a href="#cb15-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb15-5"><a href="#cb15-5" aria-hidden="true" tabindex="-1"></a><span class="ot">smellsBadM ::</span> <span class="dt">String</span> <span class="ot">-></span> <span class="dt">String</span></span>
<span id="cb15-6"><a href="#cb15-6" aria-hidden="true" tabindex="-1"></a>smellsBadM who <span class="ot">=</span> who <span class="op">++</span> <span class="st">" smells awful"</span></span>
<span id="cb15-7"><a href="#cb15-7" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb15-8"><a href="#cb15-8" aria-hidden="true" tabindex="-1"></a><span class="co">--instead of wrapping the whole function like with the applicative version we </span></span>
<span id="cb15-9"><a href="#cb15-9" aria-hidden="true" tabindex="-1"></a><span class="co">--path the argument through and then wrap the result</span></span>
<span id="cb15-10"><a href="#cb15-10" aria-hidden="true" tabindex="-1"></a><span class="ot">maybeSmellsBadM ::</span> <span class="dt">String</span> <span class="ot">-></span> <span class="dt">Maybe</span> <span class="dt">String</span></span>
<span id="cb15-11"><a href="#cb15-11" aria-hidden="true" tabindex="-1"></a>maybeSmellsBadM who <span class="ot">=</span> wrapM (smellsBadM who)</span>
<span id="cb15-12"><a href="#cb15-12" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb15-13"><a href="#cb15-13" aria-hidden="true" tabindex="-1"></a><span class="ot">maybeJamesM ::</span> <span class="dt">Maybe</span> <span class="dt">String</span></span>
<span id="cb15-14"><a href="#cb15-14" aria-hidden="true" tabindex="-1"></a>maybeJamesM <span class="ot">=</span> wrapM <span class="st">"James"</span></span>
<span id="cb15-15"><a href="#cb15-15" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb15-16"><a href="#cb15-16" aria-hidden="true" tabindex="-1"></a><span class="ot">maybeJohnM ::</span> <span class="dt">Maybe</span> <span class="dt">String</span></span>
<span id="cb15-17"><a href="#cb15-17" aria-hidden="true" tabindex="-1"></a>maybeJohnM <span class="ot">=</span> <span class="dt">Nothing</span></span>
<span id="cb15-18"><a href="#cb15-18" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb15-19"><a href="#cb15-19" aria-hidden="true" tabindex="-1"></a><span class="ot">maybeStinkyJamesM ::</span> <span class="dt">Maybe</span> <span class="dt">String</span></span>
<span id="cb15-20"><a href="#cb15-20" aria-hidden="true" tabindex="-1"></a>maybeStinkyJamesM <span class="ot">=</span> bindM maybeSmellsBadM maybeJamesM</span>
<span id="cb15-21"><a href="#cb15-21" aria-hidden="true" tabindex="-1"></a><span class="co">-- > maybeStinkyJamesM</span></span>
<span id="cb15-22"><a href="#cb15-22" aria-hidden="true" tabindex="-1"></a><span class="co">-- Just "James smells awful"</span></span>
<span id="cb15-23"><a href="#cb15-23" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb15-24"><a href="#cb15-24" aria-hidden="true" tabindex="-1"></a><span class="ot">maybeStinkyJohnM ::</span> <span class="dt">Maybe</span> <span class="dt">String</span></span>
<span id="cb15-25"><a href="#cb15-25" aria-hidden="true" tabindex="-1"></a>maybeStinkyJohnM <span class="ot">=</span> bindM maybeSmellsBadM maybeJohnM</span>
<span id="cb15-26"><a href="#cb15-26" aria-hidden="true" tabindex="-1"></a><span class="co">-- > maybeStinkyJohnM</span></span>
<span id="cb15-27"><a href="#cb15-27" aria-hidden="true" tabindex="-1"></a><span class="co">-- Nothing</span></span></code></pre></div>
<p>With a little bit of work we can get our composing values example from earlier working with the functions available from the Monad typeclass too</p>
<div class="sourceCode" id="cb16"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb16-1"><a href="#cb16-1" aria-hidden="true" tabindex="-1"></a>bindM <span class="ot">=</span> (<span class="op">=<<</span>)</span>
<span id="cb16-2"><a href="#cb16-2" aria-hidden="true" tabindex="-1"></a>wrapM <span class="ot">=</span> <span class="fu">return</span></span>
<span id="cb16-3"><a href="#cb16-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb16-4"><a href="#cb16-4" aria-hidden="true" tabindex="-1"></a><span class="ot">smellsBadM ::</span> <span class="dt">String</span> <span class="ot">-></span> <span class="dt">String</span></span>
<span id="cb16-5"><a href="#cb16-5" aria-hidden="true" tabindex="-1"></a>smellsBadM who <span class="ot">=</span> who <span class="op">++</span> <span class="st">" smells awful"</span></span>
<span id="cb16-6"><a href="#cb16-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb16-7"><a href="#cb16-7" aria-hidden="true" tabindex="-1"></a><span class="ot">maybeJamesM ::</span> <span class="dt">Maybe</span> <span class="dt">String</span></span>
<span id="cb16-8"><a href="#cb16-8" aria-hidden="true" tabindex="-1"></a>maybeJamesM <span class="ot">=</span> wrapM <span class="st">"James"</span></span>
<span id="cb16-9"><a href="#cb16-9" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb16-10"><a href="#cb16-10" aria-hidden="true" tabindex="-1"></a><span class="ot">maybeFredM ::</span> <span class="dt">Maybe</span> <span class="dt">String</span></span>
<span id="cb16-11"><a href="#cb16-11" aria-hidden="true" tabindex="-1"></a>maybeFredM <span class="ot">=</span> wrapM <span class="st">"Fred"</span></span>
<span id="cb16-12"><a href="#cb16-12" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb16-13"><a href="#cb16-13" aria-hidden="true" tabindex="-1"></a><span class="ot">maybeJohnM ::</span> <span class="dt">Maybe</span> <span class="dt">String</span></span>
<span id="cb16-14"><a href="#cb16-14" aria-hidden="true" tabindex="-1"></a>maybeJohnM <span class="ot">=</span> <span class="dt">Nothing</span></span>
<span id="cb16-15"><a href="#cb16-15" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb16-16"><a href="#cb16-16" aria-hidden="true" tabindex="-1"></a><span class="ot">maybeBothSmellBadM ::</span> <span class="dt">String</span> <span class="ot">-></span> <span class="dt">String</span> <span class="ot">-></span> <span class="dt">Maybe</span> <span class="dt">String</span></span>
<span id="cb16-17"><a href="#cb16-17" aria-hidden="true" tabindex="-1"></a>maybeBothSmellBadM who1 who2 <span class="ot">=</span> </span>
<span id="cb16-18"><a href="#cb16-18" aria-hidden="true" tabindex="-1"></a> wrapM ((smellsBadM who1) <span class="op">++</span> <span class="st">", but "</span> <span class="op">++</span> (smellsBadM who2) <span class="op">++</span> <span class="st">" too!"</span>)</span>
<span id="cb16-19"><a href="#cb16-19" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb16-20"><a href="#cb16-20" aria-hidden="true" tabindex="-1"></a><span class="ot">maybeBothSmellBadM2 ::</span> <span class="dt">Maybe</span> <span class="dt">String</span> <span class="ot">-></span> <span class="dt">String</span> <span class="ot">-></span> <span class="dt">Maybe</span> <span class="dt">String</span></span>
<span id="cb16-21"><a href="#cb16-21" aria-hidden="true" tabindex="-1"></a>maybeBothSmellBadM2 who2 who1 <span class="ot">=</span> bindM (maybeBothSmellBadM who1) who2</span>
<span id="cb16-22"><a href="#cb16-22" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb16-23"><a href="#cb16-23" aria-hidden="true" tabindex="-1"></a><span class="ot">maybeJamesFredBothSmellM ::</span> <span class="dt">Maybe</span> <span class="dt">String</span></span>
<span id="cb16-24"><a href="#cb16-24" aria-hidden="true" tabindex="-1"></a>maybeJamesFredBothSmellM <span class="ot">=</span> bindM (maybeBothSmellBadM2 maybeJamesM) maybeFredM</span>
<span id="cb16-25"><a href="#cb16-25" aria-hidden="true" tabindex="-1"></a><span class="co">-- > maybeJamesFredBothSmellM</span></span>
<span id="cb16-26"><a href="#cb16-26" aria-hidden="true" tabindex="-1"></a><span class="co">-- Just "Fred smells awful, but James smells awful too!"</span></span>
<span id="cb16-27"><a href="#cb16-27" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb16-28"><a href="#cb16-28" aria-hidden="true" tabindex="-1"></a><span class="ot">maybeJamesJohnBothSmellM ::</span> <span class="dt">Maybe</span> <span class="dt">String</span></span>
<span id="cb16-29"><a href="#cb16-29" aria-hidden="true" tabindex="-1"></a>maybeJamesJohnBothSmellM <span class="ot">=</span> bindM (maybeBothSmellBadM2 maybeJamesM) maybeJohnM</span>
<span id="cb16-30"><a href="#cb16-30" aria-hidden="true" tabindex="-1"></a><span class="co">-- > maybeJamesJohnBothSmellM</span></span>
<span id="cb16-31"><a href="#cb16-31" aria-hidden="true" tabindex="-1"></a><span class="co">-- Nothing</span></span></code></pre></div>
<p>Notice that in this example the ordering is opposite from what we found from using Applicative’s apply. With apply we have two Maybe values, one of which is a function, and compose them together going left to right. With Monad’s bind, this is no longer the case, but rather we have a function that takes the unwrapped value from the second Maybe value and returns another Maybe value from it, therefore making the order right to left.</p>
<p>With the move from the Functor typeclass to the Applicative typeclass we moved from being able to modify the value wrapped inside the datatype that implements the Functor typeclass to the ability to compose different separately wrapped elements in a datatype that implements the Applicative typeclasss together, so when we make the jump from Applicative to Monad, what new ability do we get? From comparing the types between bind and apply we can see that for the first time we no longer have our functions resulting value prewrapped for us. This comes in useful if the function we want to apply to the unwrapped value, itself already produces a wrapped value. If we had that scenario with only an Applicative we would have no way to avoid nesting. In fact one cool benefit of Monad’s bind is that if we are given an already nested structure (for example if apply was used when bind should have been used), we can flatten it by just using the bind and identity functions.</p>
<div class="sourceCode" id="cb17"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb17-1"><a href="#cb17-1" aria-hidden="true" tabindex="-1"></a>bindM <span class="ot">=</span> (<span class="op">=<<</span>)</span>
<span id="cb17-2"><a href="#cb17-2" aria-hidden="true" tabindex="-1"></a>wrapM <span class="ot">=</span> <span class="fu">return</span></span>
<span id="cb17-3"><a href="#cb17-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb17-4"><a href="#cb17-4" aria-hidden="true" tabindex="-1"></a><span class="ot">identityM ::</span> <span class="dt">Maybe</span> <span class="dt">String</span> <span class="ot">-></span> <span class="dt">Maybe</span> <span class="dt">String</span></span>
<span id="cb17-5"><a href="#cb17-5" aria-hidden="true" tabindex="-1"></a>identityM value <span class="ot">=</span> value</span>
<span id="cb17-6"><a href="#cb17-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb17-7"><a href="#cb17-7" aria-hidden="true" tabindex="-1"></a><span class="ot">maybeJamesM ::</span> <span class="dt">Maybe</span> <span class="dt">String</span></span>
<span id="cb17-8"><a href="#cb17-8" aria-hidden="true" tabindex="-1"></a>maybeJamesM <span class="ot">=</span> wrapM <span class="st">"James"</span></span>
<span id="cb17-9"><a href="#cb17-9" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb17-10"><a href="#cb17-10" aria-hidden="true" tabindex="-1"></a><span class="ot">nestedMaybeJamesM ::</span> <span class="dt">Maybe</span> (<span class="dt">Maybe</span> <span class="dt">String</span>)</span>
<span id="cb17-11"><a href="#cb17-11" aria-hidden="true" tabindex="-1"></a>nestedMaybeJamesM <span class="ot">=</span> wrapM maybeJamesM</span>
<span id="cb17-12"><a href="#cb17-12" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb17-13"><a href="#cb17-13" aria-hidden="true" tabindex="-1"></a><span class="ot">unNestedMaybeJamesM ::</span> <span class="dt">Maybe</span> <span class="dt">String</span></span>
<span id="cb17-14"><a href="#cb17-14" aria-hidden="true" tabindex="-1"></a>unNestedMaybeJamesM <span class="ot">=</span> bindM identityM nestedMaybeJamesM</span>
<span id="cb17-15"><a href="#cb17-15" aria-hidden="true" tabindex="-1"></a><span class="co">-- > unNestedMaybeJamesM</span></span>
<span id="cb17-16"><a href="#cb17-16" aria-hidden="true" tabindex="-1"></a><span class="co">-- Just "James"</span></span>
<span id="cb17-17"><a href="#cb17-17" aria-hidden="true" tabindex="-1"></a><span class="co">-- > unNestedMaybeJamesM == maybeJamesM</span></span>
<span id="cb17-18"><a href="#cb17-18" aria-hidden="true" tabindex="-1"></a><span class="co">-- True</span></span></code></pre></div>
<p>A practical use of this again shows up when using linked lists, bind even appears for this purpose in some other languages under the guise of flatMap, a function identical to bind specified to Lists. For example suppose I wanted to map a function over a list of values, but instead of just returning one value for each, I want to return several. One option to take care of this problem is to return a lists of lists, but this quickly becomes cumbersome when going several levels deep. Instead I can use Monad’s bind to accumulate all the results in one (non-nested) list. Here we use bind to generate <a href="https://en.wikipedia.org/wiki/Backronym">backronyms</a></p>
<div class="sourceCode" id="cb18"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb18-1"><a href="#cb18-1" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span> <span class="dt">Data.List</span></span>
<span id="cb18-2"><a href="#cb18-2" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span> <span class="dt">Data.Char</span></span>
<span id="cb18-3"><a href="#cb18-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb18-4"><a href="#cb18-4" aria-hidden="true" tabindex="-1"></a>bindM <span class="ot">=</span> (<span class="op">=<<</span>)</span>
<span id="cb18-5"><a href="#cb18-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb18-6"><a href="#cb18-6" aria-hidden="true" tabindex="-1"></a><span class="co">-- Using a List for convenience for my (very short) word dictonary </span></span>
<span id="cb18-7"><a href="#cb18-7" aria-hidden="true" tabindex="-1"></a><span class="ot">wordDictonaryM ::</span> [<span class="dt">String</span>]</span>
<span id="cb18-8"><a href="#cb18-8" aria-hidden="true" tabindex="-1"></a>wordDictonaryM <span class="ot">=</span> [<span class="st">"Resistance"</span>, <span class="st">"External"</span>, <span class="st">"Frog-legs"</span>, <span class="st">"Combined"</span>, <span class="st">"Load-"</span>, </span>
<span id="cb18-9"><a href="#cb18-9" aria-hidden="true" tabindex="-1"></a> <span class="st">"Understated"</span>, <span class="st">"Bearing"</span>, <span class="st">"Operational"</span>, <span class="st">"Treadmill"</span>]</span>
<span id="cb18-10"><a href="#cb18-10" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb18-11"><a href="#cb18-11" aria-hidden="true" tabindex="-1"></a><span class="co">-- String is just a List of Char [Char]</span></span>
<span id="cb18-12"><a href="#cb18-12" aria-hidden="true" tabindex="-1"></a><span class="ot">backronymM ::</span> <span class="dt">String</span></span>
<span id="cb18-13"><a href="#cb18-13" aria-hidden="true" tabindex="-1"></a><span class="co">-- Stephen </span></span>
<span id="cb18-14"><a href="#cb18-14" aria-hidden="true" tabindex="-1"></a>backronymM <span class="ot">=</span> <span class="st">"Colbert"</span></span>
<span id="cb18-15"><a href="#cb18-15" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb18-16"><a href="#cb18-16" aria-hidden="true" tabindex="-1"></a><span class="ot">findWordM ::</span> <span class="dt">Char</span> <span class="ot">-></span> <span class="dt">String</span></span>
<span id="cb18-17"><a href="#cb18-17" aria-hidden="true" tabindex="-1"></a><span class="co">-- Don't let the anonymous function scare you. They are functions that don't have</span></span>
<span id="cb18-18"><a href="#cb18-18" aria-hidden="true" tabindex="-1"></a><span class="co">-- any name -- which makes them useful when they are short, and you only need to </span></span>
<span id="cb18-19"><a href="#cb18-19" aria-hidden="true" tabindex="-1"></a><span class="co">-- use them once. In this case this anonymous function only has one argument "x"</span></span>
<span id="cb18-20"><a href="#cb18-20" aria-hidden="true" tabindex="-1"></a>findWordM c <span class="ot">=</span> <span class="kw">case</span> find (\x <span class="ot">-></span> <span class="fu">head</span> x <span class="op">==</span> <span class="fu">toUpper</span> c) wordDictonaryM <span class="kw">of</span></span>
<span id="cb18-21"><a href="#cb18-21" aria-hidden="true" tabindex="-1"></a> <span class="dt">Just</span> x <span class="ot">-></span> x <span class="op">++</span> <span class="st">" "</span></span>
<span id="cb18-22"><a href="#cb18-22" aria-hidden="true" tabindex="-1"></a> <span class="dt">Nothing</span> <span class="ot">-></span> c <span class="op">:</span> <span class="st">" "</span></span>
<span id="cb18-23"><a href="#cb18-23" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb18-24"><a href="#cb18-24" aria-hidden="true" tabindex="-1"></a><span class="ot">aTreadmillM ::</span> <span class="dt">String</span></span>
<span id="cb18-25"><a href="#cb18-25" aria-hidden="true" tabindex="-1"></a>aTreadmillM <span class="ot">=</span> bindM findWordM backronymM</span>
<span id="cb18-26"><a href="#cb18-26" aria-hidden="true" tabindex="-1"></a><span class="co">-- > aTreadmillM</span></span>
<span id="cb18-27"><a href="#cb18-27" aria-hidden="true" tabindex="-1"></a><span class="co">-- "Combined Operational Load- Bearing External Resistance Treadmill "</span></span></code></pre></div>
<p>And that’s really all there is too these scary typeclasses. Just like in Java where you have some Objects where it’s not possible to directly change the inner state, in Haskell you have some datatypes that also don’t allow directly changing their inner variable(s). Just like in Java where if we know what class the Object inherits from we can use certain generic functions on them, in Haskell we have typeclasses, and if a datatype implements a certain typeclass, we can be sure there will be certain functions that will work on it.</p>
<aside id="footnotes" class="footnotes footnotes-end-of-document" role="doc-endnotes">
<hr />
<ol>
<li id="fn1"><p>Two functions, but only one new one. The other one (return) is simply an alias to our previously mentioned wrap (aka pure)<a href="#fnref1" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
</ol>
</aside>
<div class="comments">
This article is being discussed on <a href="https://news.ycombinator.com/item?id=15080989">Hacker News</a>
</div>
]]></summary>
</entry>
<entry>
<title>The Very First Post</title>
<link href="http://joyfulmantis.github.io/posts/2014-11-14-the-very-first-post.html" />
<id>http://joyfulmantis.github.io/posts/2014-11-14-the-very-first-post.html</id>
<published>2014-11-14T00:00:00Z</published>
<updated>2014-11-14T00:00:00Z</updated>
<summary type="html"><![CDATA[<!-- <div class="info"> -->
<!-- Posted on November 14, 2014 -->
<!-- -->
<!-- </div> -->
<p>This post is a very special post, the firstborn of many posts to come.</p>
<p>Our post came in to this world on a nice nearly white sheet of emacs markdown-mode, and the very earth quaked (or at least should have) in the terror of his coming.</p>
]]></summary>
</entry>
</feed>