-
Notifications
You must be signed in to change notification settings - Fork 0
/
Week3_Notes.html
445 lines (344 loc) · 23.3 KB
/
Week3_Notes.html
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
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
<!DOCTYPE html><html><head><meta charset="utf-8">
<link rel="stylesheet" type="text/css" href="styles.css">
<title>Week3_Notes</title></head><body><article class="markdown-body"><h1>
<a id="week3-notes-of-data-structures-and-types----functional-programming-in-haskell-mooc" class="anchor" href="#week3-notes-of-data-structures-and-types----functional-programming-in-haskell-mooc" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Week3 Notes of "Data Structures And Types" -- "Functional Programming in Haskell" MOOC</h1>
<h2>
<a id="contents" class="anchor" href="#contents" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Contents</h2>
<ul>
<li>
<a href="#functions-on-lists">Functions on Lists</a>
<ul>
<li>
<a href="#recursion-and-lists">Recursion and lists</a>
<ul>
<li><a href="#length-function"><code>length</code> function</a></li>
<li><a href="#filter-function"><code>filter</code> function</a></li>
</ul>
</li>
<li>
<a href="#computations-over-lists">Computations over lists</a>
<ul>
<li><a href="#function-composition">Function composition</a></li>
</ul>
</li>
<li><a href="#map-function"><code>map</code> function</a></li>
<li>
<a href="#folding-a-list-reduction">Folding a list (reduction)</a>
<ul>
<li><a href="#left-fold-foldl">Left fold: <code>foldl</code></a></li>
<li><a href="#right-fold-foldr">Right fold: <code>foldr</code></a></li>
</ul>
</li>
<li><a href="#maps-and-folds-versus-loops">Maps and Folds versus Loops</a></li>
<li><a href="#summary-of-map-and-folds">Summary of Map and Folds</a></li>
</ul>
</li>
<li>
<a href="#custom-data-types">Custom Data Types</a>
<ul>
<li>
<a href="#user-defined-data-types">User defined data types</a>
<ul>
<li><a href="#sum-data-type">Sum Data Type</a></li>
<li><a href="#record-or-product-data-type">Record or Product Data Type</a></li>
</ul>
</li>
<li><a href="#type-classes">Type Classes</a></li>
</ul>
</li>
<li><a href="#haskell-history">Haskell History</a></li>
</ul>
<hr>
<h2>
<a id="functions-on-lists" class="anchor" href="#functions-on-lists" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Functions on Lists</h2>
<h3>
<a id="recursion-and-lists" class="anchor" href="#recursion-and-lists" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Recursion and lists</h3>
<ul>
<li>Every list must be either
<ul>
<li>
<code>[]</code> or</li>
<li>
<code>(x:xs)</code> for some <code>x</code> (the <code>head</code> of the list) and <code>xs</code> (the <code>tail</code>) where <code>(x:xs)</code> is pronounced as <code>x cons xs</code>.</li>
</ul>
</li>
<li>The recursive definition follows the structure of the data:
<ul>
<li>Base case of the recursion is <code>[]</code>.</li>
<li>Recursion (or induction) case is <code>(x:xs)</code>.</li>
</ul>
</li>
</ul>
<h4>
<a id="length-function" class="anchor" href="#length-function" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a><code>length</code> function</h4>
<ul>
<li>Recursive definition of <code>length</code>:</li>
</ul>
<div class="highlight highlight-source-haskell"><pre><span class="pl-en">length</span> <span class="pl-k">::</span> [<span class="pl-smi">a</span>] <span class="pl-k">-></span> <span class="pl-en"><span class="pl-c1">Int</span></span>
<span class="pl-c1">length</span> <span class="pl-c1">[]</span> = <span class="pl-c1">0</span> # base <span class="pl-k">case</span>
<span class="pl-c1">length</span> (x:xs) = <span class="pl-c1">1</span> + <span class="pl-c1">length</span> xs # recursion <span class="pl-k">case</span></pre></div>
<ul>
<li>Example:</li>
</ul>
<div class="highlight highlight-source-haskell"><pre><span class="pl-c1">length</span> [<span class="pl-c1">1</span>..<span class="pl-c1">10</span>] <span class="pl-c">-- > 10</span></pre></div>
<h4>
<a id="filter-function" class="anchor" href="#filter-function" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a><code>filter</code> function</h4>
<ul>
<li>
<code>filter</code> is given a predicate (a function that gives a Boolean result) and a list, and returns a list of the elements that satisfy the predicate.</li>
</ul>
<div class="highlight highlight-source-haskell"><pre><span class="pl-en">filter</span> <span class="pl-k">::</span> (<span class="pl-smi">a</span><span class="pl-k">-></span><span class="pl-en"><span class="pl-c1">Bool</span></span>) <span class="pl-k">-></span> [<span class="pl-smi">a</span>] <span class="pl-k">-></span> [<span class="pl-smi">a</span>]</pre></div>
<ul>
<li>Example:</li>
</ul>
<div class="highlight highlight-source-haskell"><pre><span class="pl-c1">filter</span> (<<span class="pl-c1">5</span>) [<span class="pl-c1">3</span>,<span class="pl-c1">9</span>,<span class="pl-c1">2</span>,<span class="pl-c1">12</span>,<span class="pl-c1">6</span>,<span class="pl-c1">4</span>] <span class="pl-c">-- > [3,2,4]</span></pre></div>
<ul>
<li>Recursive definition of <code>filter</code>:</li>
</ul>
<div class="highlight highlight-source-haskell"><pre><span class="pl-en">filter</span> <span class="pl-k">::</span> (<span class="pl-smi">a</span> <span class="pl-k">-></span> <span class="pl-en"><span class="pl-c1">Bool</span></span>) <span class="pl-k">-></span> [<span class="pl-smi">a</span>] <span class="pl-k">-></span> [<span class="pl-smi">a</span>]
<span class="pl-c1">filter</span> <span class="pl-c1">pred</span> <span class="pl-c1">[]</span> = <span class="pl-c1">[]</span>
<span class="pl-c1">filter</span> <span class="pl-c1">pred</span> (x:xs)
| <span class="pl-c1">pred</span> x = x : <span class="pl-c1">filter</span> <span class="pl-c1">pred</span> xs
| <span class="pl-c1">otherwise</span> = <span class="pl-c1">filter</span> <span class="pl-c1">pred</span> xs</pre></div>
<h3>
<a id="computations-over-lists" class="anchor" href="#computations-over-lists" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Computations over lists</h3>
<ul>
<li>
<code>for</code> / <code>while</code> loops in an imperative language are naturally expressed as list computations in a functional language.
<ul>
<li>Perform a computation on each element of a list: <code>map</code>
</li>
<li>Iterate over a list:
<ul>
<li>from left to right: <code>foldl</code>;</li>
<li>from right to left: <code>foldr</code>
</li>
</ul>
</li>
</ul>
</li>
</ul>
<h4>
<a id="function-composition" class="anchor" href="#function-composition" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Function composition</h4>
<ul>
<li>Express a large computation by "chaining together" a sequence of functions that perform smaller computations.
<ul>
<li>The entire computation (first <code>g</code>, then <code>f</code>) is written as <code>f ∘ g</code> (traditional mathematical notation).</li>
<li>In <code>f ∘ g</code>, the functions are used in right to left order.</li>
<li>Haskell uses <code>.</code> as the function composition operator.</li>
</ul>
</li>
</ul>
<div class="highlight highlight-source-haskell"><pre>(.) <span class="pl-k">::</span> (<span class="pl-smi">b</span><span class="pl-k">-></span><span class="pl-smi">c</span>) <span class="pl-k">-></span> (<span class="pl-smi">a</span><span class="pl-k">-></span><span class="pl-smi">b</span>) <span class="pl-k">-></span> <span class="pl-smi">a</span> <span class="pl-k">-></span> <span class="pl-smi">c</span>
(f . g) x = f (g x)</pre></div>
<h3>
<a id="map-function" class="anchor" href="#map-function" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a><code>map</code> function</h3>
<ul>
<li>
<code>map</code> applies a function to every element of a list.</li>
</ul>
<div class="highlight highlight-source-haskell"><pre><span class="pl-c1">map</span> f [x0,x1,x2] <span class="pl-c">-- > [f x0, f x1, f x2]</span></pre></div>
<ul>
<li>Common style is to define a set of simple computations using <code>map</code>, and to compose them.</li>
</ul>
<div class="highlight highlight-source-haskell"><pre><span class="pl-c1">map</span> f (<span class="pl-c1">map</span> g xs) = <span class="pl-c1">map</span> (f . g) xs</pre></div>
<ul>
<li>Recursive definition of <code>map</code>:</li>
</ul>
<div class="highlight highlight-source-haskell"><pre><span class="pl-en">map</span> <span class="pl-k">::</span> (<span class="pl-smi">a</span> <span class="pl-k">-></span> <span class="pl-smi">b</span>) <span class="pl-k">-></span> [<span class="pl-smi">a</span>] <span class="pl-k">-></span> [<span class="pl-smi">b</span>]
<span class="pl-c1">map</span> _ <span class="pl-c1">[]</span> = <span class="pl-c1">[]</span>
<span class="pl-c1">map</span> f (x:xs) = f x : <span class="pl-c1">map</span> f xs</pre></div>
<h3>
<a id="folding-a-list-reduction" class="anchor" href="#folding-a-list-reduction" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Folding a list (reduction)</h3>
<ul>
<li>An iteration over a list to produce a singleton value is called a <code>fold</code>.</li>
</ul>
<h4>
<a id="left-fold-foldl" class="anchor" href="#left-fold-foldl" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Left fold: <code>foldl</code>
</h4>
<ul>
<li>
<code>foldl</code> is fold from the left.</li>
<li>Typical application is <code>foldl f z xs</code>
<ul>
<li>The <code>z::b</code> is an initial value [or can be treated as an accumulator].</li>
<li>The <code>xs::[a]</code> argument is a list of values which we combine systematically using the supplied function <code>f</code>.</li>
</ul>
</li>
<li>Recursive definition of <code>foldl</code>:</li>
</ul>
<div class="highlight highlight-source-haskell"><pre><span class="pl-en">foldl</span> <span class="pl-k">::</span> (<span class="pl-smi">b</span> <span class="pl-k">-></span> <span class="pl-smi">a</span> <span class="pl-k">-></span> <span class="pl-smi">b</span>) <span class="pl-k">-></span> <span class="pl-smi">b</span> <span class="pl-k">-></span> [<span class="pl-smi">a</span>] <span class="pl-k">-></span> <span class="pl-smi">b</span>
<span class="pl-c1">foldl</span> f z0 xs0 = lgo z0 xs0
<span class="pl-k">where</span>
lgo z <span class="pl-c1">[]</span> = z
lgo z (x:xs) = lgo (f z x) xs</pre></div>
<ul>
<li>Example of <code>foldl</code> function with <code>(+)</code> as infix function:</li>
</ul>
<div class="highlight highlight-source-haskell"><pre><span class="pl-c1">foldl</span> (+) z [x0,x1,x2] <span class="pl-c">-- > ((z + x0) + x1) + x2</span></pre></div>
<ul>
<li>Or <code>foldl</code> function can be summarized as:</li>
</ul>
<div class="highlight highlight-source-haskell"><pre><span class="pl-c1">foldl</span> f z [x0,x1,x2] <span class="pl-c">-- > f (f (f z x0) x1) x2</span></pre></div>
<h4>
<a id="right-fold-foldr" class="anchor" href="#right-fold-foldr" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Right fold: <code>foldr</code>
</h4>
<ul>
<li>Similar to <code>foldl</code>, but <code>foldr</code> is fold from the right to left.</li>
<li>typical application is <code>foldr f z xs</code>
<ul>
<li>The <code>z::b</code> is an initial value [or can be treated as an accumulator].</li>
<li>The <code>xs::[a]</code> argument is a list of values which we combine systematically using the supplied function <code>f</code>.</li>
</ul>
</li>
<li>Recursive definition of <code>foldl</code>:</li>
</ul>
<div class="highlight highlight-source-haskell"><pre><span class="pl-en">foldr</span> <span class="pl-k">::</span> (<span class="pl-smi">a</span> <span class="pl-k">-></span> <span class="pl-smi">b</span> <span class="pl-k">-></span> <span class="pl-smi">b</span>) <span class="pl-k">-></span> <span class="pl-smi">b</span> <span class="pl-k">-></span> [<span class="pl-smi">a</span>] <span class="pl-k">-></span> <span class="pl-smi">b</span>
<span class="pl-c1">foldr</span> k z = go
<span class="pl-k">where</span>
go <span class="pl-c1">[]</span> = z
go (y:ys) = y <span class="pl-k">`k`</span> go ys</pre></div>
<ul>
<li>Example of <code>foldr</code> function with <code>(+)</code> as infix function:</li>
</ul>
<div class="highlight highlight-source-haskell"><pre><span class="pl-c1">foldr</span> (+) z [x0,x1,x2] <span class="pl-c">-- > x0 + (x1 + (x2 + z))</span></pre></div>
<ul>
<li>Or <code>foldr</code> function can be summarized as:</li>
</ul>
<div class="highlight highlight-source-haskell"><pre><span class="pl-c1">foldr</span> f z [x0,x1,x2] <span class="pl-c">-- > f x0 (f x1 (f x2 z))</span></pre></div>
<ul>
<li>A list can be constructed with <code>foldr</code> as <code>foldr cons [] xs = xs</code>.</li>
</ul>
<div class="highlight highlight-source-haskell"><pre><span class="pl-c1">foldr</span> (:) <span class="pl-c1">[]</span> [x0,x1,x2] <span class="pl-c">-- > x0 : x1 : x2 : []</span></pre></div>
<ul>
<li>Examples of <code>foldr</code>:</li>
</ul>
<div class="highlight highlight-source-haskell"><pre><span class="pl-c1">sum</span> xs = <span class="pl-c1">foldr</span> (+) <span class="pl-c1">0</span> xs
<span class="pl-c1">product</span> xs = <span class="pl-c1">foldr</span> (*) <span class="pl-c1">1</span> xs</pre></div>
<h3>
<a id="maps-and-folds-versus-loops" class="anchor" href="#maps-and-folds-versus-loops" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Maps and Folds versus Loops</h3>
<ul>
<li>For list operations, it is usually easier to use higher-order functions like:
<ul>
<li>
<code>map</code> for performing an operation on every element of a list</li>
<li>
<code>foldl</code> / <code>foldr</code> for reducing a list to a single value.</li>
</ul>
</li>
<li>Sometimes these functions are referred to as list combinators.</li>
</ul>
<div class="highlight highlight-source-haskell"><pre><span class="pl-c">-- a list</span>
lst = [<span class="pl-c1">1</span>.. <span class="pl-c1">10</span>]
<span class="pl-c">-- map</span>
f x = x * (x + <span class="pl-c1">1</span>)
lst_ = <span class="pl-c1">map</span> f lst
<span class="pl-c">-- foldl</span>
g = (/)
accl = <span class="pl-c1">foldl</span> g <span class="pl-c1">1</span> lst <span class="pl-c">-- > ((((((((((1 / 1) / 2) / 3) / 4) / 5) / 6) / 7) / 8) / 9) / 10) = 2.7557319223985894e-7</span>
<span class="pl-c">-- foldr</span>
g' = (/)
accr = <span class="pl-c1">foldr</span> g' <span class="pl-c1">1</span> lst <span class="pl-c">-- > 1 / (2 / (3 / (4 / (5 / (6 / (7 / (8 / (9 / (10 / 1))))))))) = 0.24609375</span>
<span class="pl-c">-- main</span>
main = <span class="pl-k">do</span>
<span class="pl-c1">print</span> lst_ <span class="pl-c">-- > [2.0,6.0,12.0,20.0,30.0,42.0,56.0,72.0,90.0,110.0]</span>
<span class="pl-c1">print</span> accl <span class="pl-c">-- > 2.7557319223985894e-7</span>
<span class="pl-c1">print</span> accr <span class="pl-c">-- > 0.24609375</span></pre></div>
<h4>
<a id="summary-of-map-and-folds" class="anchor" href="#summary-of-map-and-folds" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Summary of Map and Folds</h4>
<ul>
<li>
<code>map</code>: loop over list element-by-element, append new element to new list.</li>
<li>
<code>foldl</code>: loop over list element-by-element, update accumulator using current accumulator and element.</li>
<li>
<code>foldr</code>: loop over reverse list element-by-element, update accumulator using current accumulator and element.</li>
</ul>
<div class="highlight highlight-source-haskell"><pre><span class="pl-en">map</span> <span class="pl-k">::</span> (<span class="pl-smi">a</span> <span class="pl-k">-></span> <span class="pl-smi">b</span>) <span class="pl-k">-></span> [<span class="pl-smi">a</span>] <span class="pl-k">-></span> [<span class="pl-smi">b</span>]
<span class="pl-en">foldl</span> <span class="pl-k">::</span> (<span class="pl-smi">b</span> <span class="pl-k">-></span> <span class="pl-smi">a</span> <span class="pl-k">-></span> <span class="pl-smi">b</span>) <span class="pl-k">-></span> <span class="pl-smi">b</span> <span class="pl-k">-></span> [<span class="pl-smi">a</span>] <span class="pl-k">-></span> <span class="pl-smi">b</span>
<span class="pl-en">foldr</span> <span class="pl-k">::</span> (<span class="pl-smi">a</span> <span class="pl-k">-></span> <span class="pl-smi">b</span> <span class="pl-k">-></span> <span class="pl-smi">b</span>) <span class="pl-k">-></span> <span class="pl-smi">b</span> <span class="pl-k">-></span> [<span class="pl-smi">a</span>] <span class="pl-k">-></span> <span class="pl-smi">b</span></pre></div>
<hr>
<h2>
<a id="custom-data-types" class="anchor" href="#custom-data-types" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Custom Data Types</h2>
<h3>
<a id="user-defined-data-types" class="anchor" href="#user-defined-data-types" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>User defined data types</h3>
<ul>
<li>Combining the basic types [like Int, Bool, etc] we can generate custom data types, using algebraic sums and products.</li>
<li>Custom data types are called algebraic data types.</li>
<li>Keyword <code>data</code> indicates we are defining a new type.</li>
<li>The name of the type and the names of the values should start with capital letters.</li>
</ul>
<h4>
<a id="sum-data-type" class="anchor" href="#sum-data-type" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Sum Data Type</h4>
<ul>
<li>The alternative values are separated with a vertical bar character (<code>|</code>).</li>
<li>The alternative values relate to algebraic sums.</li>
<li>
<code>deriving Show</code> is required for printing values of custom data types.</li>
</ul>
<div class="highlight highlight-source-haskell"><pre><span class="pl-k">data</span> <span class="pl-en">SimpleNum</span> <span class="pl-k">=</span> <span class="pl-ent">One</span> | <span class="pl-ent">Two</span> | <span class="pl-ent">Many</span> <span class="pl-k">deriving</span> <span class="pl-e">Show</span>
<span class="pl-k">let</span> convert <span class="pl-c1">1</span> = <span class="pl-ent">One</span>
convert <span class="pl-c1">2</span> = <span class="pl-ent">Two</span>
convert _ = <span class="pl-ent">Many</span>
:t <span class="pl-ent">One</span> <span class="pl-c">-- > One :: SimpleNum</span>
convert <span class="pl-c1">1</span> <span class="pl-c">-- > One</span>
convert <span class="pl-c1">50</span> <span class="pl-c">-- > Many</span>
<span class="pl-c1">map</span> convert [<span class="pl-c1">1</span>..<span class="pl-c1">5</span>] <span class="pl-c">-- > [One, Two, Many, Many, Many]</span></pre></div>
<h4>
<a id="record-or-product-data-type" class="anchor" href="#record-or-product-data-type" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Record or Product Data Type</h4>
<ul>
<li>Stores portfolio of values.</li>
<li>The record values relate to algebraic products.</li>
</ul>
<div class="highlight highlight-source-haskell"><pre><span class="pl-k">data</span> <span class="pl-en">CricketScore</span> <span class="pl-k">=</span> <span class="pl-ent">Score</span> [<span class="pl-en"><span class="pl-c1">Char</span></span>] <span class="pl-en"><span class="pl-c1">Int</span></span> <span class="pl-en"><span class="pl-c1">Int</span></span> <span class="pl-k">deriving</span> <span class="pl-e">Show</span>
<span class="pl-k">let</span> x = <span class="pl-ent">Score</span> <span class="pl-s"><span class="pl-pds">"</span>England<span class="pl-pds">"</span></span> <span class="pl-c1">255</span> <span class="pl-c1">10</span>
:t x <span class="pl-c">-- > CricketScore</span></pre></div>
<h3>
<a id="type-classes" class="anchor" href="#type-classes" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Type Classes</h3>
<ul>
<li>The type class constrains member types to provide functions that conform to certain type signatures effectively, API constraints.</li>
<li>Type classes are like interfaces in Java.
<ul>
<li>Types in the type class are like concrete implementations of the interface.</li>
</ul>
</li>
<li>Type classes provide a neat mechanism to enable operator overloading in Haskell.</li>
<li>A Type class is a generalized family of similar types.
<ul>
<li>
<code>Num</code> is a type class, which specifies a family of types including integer and floating-point types.</li>
<li>With <code>Eq</code> type class, we can compare values of such types equality with the (<code>==</code>) operator.</li>
<li>With <code>Ord</code> type class, we can order values of such types with relational operators like less than (<code><</code>) and greater than (<code>></code>).
<ul>
<li>For strings, less than (<code><</code>) implements a lexicographic ordering.</li>
</ul>
</li>
<li>With <code>Show</code> type class, we can generate string values that represent values of such types, like <code>toString()</code> in Java.</li>
<li>With <code>Read</code> type class, we can generate values of such types from string values.</li>
</ul>
</li>
</ul>
<div class="highlight highlight-source-haskell"><pre><span class="pl-k">data</span> <span class="pl-en">SimpleNum</span> <span class="pl-k">=</span> <span class="pl-ent">One</span> | <span class="pl-ent">Two</span> | <span class="pl-ent">Many</span> <span class="pl-k">deriving</span> (<span class="pl-e">Eq</span>, <span class="pl-e">Ord</span>, <span class="pl-e">Show</span>, <span class="pl-e">Read</span>)
<span class="pl-c">-- Show</span>
<span class="pl-c1">show</span> <span class="pl-ent">One</span> <span class="pl-c">-- > "One"</span>
<span class="pl-c1">show</span> <span class="pl-ent">Many</span> <span class="pl-c">-- > "Many"</span>
<span class="pl-c">-- Read</span>
<span class="pl-c1">read</span> <span class="pl-s"><span class="pl-pds">"</span>One<span class="pl-pds">"</span></span> <span class="pl-k">::</span> <span class="pl-en">SimpleNum</span> <span class="pl-c">-- > One</span>
<span class="pl-c">-- Eq</span>
<span class="pl-ent">One</span> == <span class="pl-ent">One</span> <span class="pl-c">-- > True</span>
<span class="pl-ent">One</span> == <span class="pl-ent">Two</span> <span class="pl-c">-- > False</span>
<span class="pl-c">-- Ord</span>
<span class="pl-ent">One</span> <= <span class="pl-ent">Two</span> <span class="pl-c">-- > True</span>
:t (+) <span class="pl-c">-- > (+) :: Num a => a -> a -> a</span>
:t (==) <span class="pl-c">-- > (==) :: Eq a => a -> a -> Bool</span>
:t (<) <span class="pl-c">-- > (<) :: Ord a => a -> a -> Bool</span>
</pre></div>
<hr>
<h2>
<a id="haskell-history" class="anchor" href="#haskell-history" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Haskell History</h2>
<ul>
<li>Please check Future Learn FP MOOC page for a <a href="https://www.futurelearn.com/courses/functional-programming-haskell/1/steps/115453">brief history of Haskell</a>.</li>
</ul>
</article>
</body>
</html>