-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathHRGettingStarted.html
1290 lines (1060 loc) Β· 54.2 KB
/
HRGettingStarted.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
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
<!-- 2022-12-15 Thu 12:10 -->
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Haskell Road; Getting Started</title>
<meta name="generator" content="Org Mode" />
<link rel="stylesheet" href="./tufte.css" type="text/css">
<style> .title { display: none; } </style>
<style> caption.t-bottom { caption-side: bottom; } </style>
<script>
window.MathJax = {
tex: {
ams: {
multlineWidth: '85%'
},
tags: 'ams',
tagSide: 'right',
tagIndent: '.8em'
},
chtml: {
scale: 1.0,
displayAlign: 'center',
displayIndent: '0em'
},
svg: {
scale: 1.0,
displayAlign: 'center',
displayIndent: '0em'
},
output: {
font: 'mathjax-dejavu',
displayOverflow: 'overflow'
}
};
</script>
<script
id="MathJax-script"
async
src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js">
</script>
</head>
<body>
<div id="content" class="content">
<h1 class="title">Haskell Road; Getting Started</h1>
<div class="header">
<link rel="stylesheet" href="hamb.css">
<link rel="stylesheet" href="tufte.css">
<img src="./images/heading6.png" style="padding: 0px 0px 22px 0px" alt="3-d graph" class="center">
<p>
<nav role="navigation">
<div id="menuToggle">
<!--
A fake / hidden checkbox is used as click reciever,
so you can use the :checked selector on it.
-->
<input type="checkbox" />
<!--
Some spans to act as a hamburger.
They are acting like a real hamburger,
not that McDonalds stuff.
-->
<span></span>
<span></span>
<span></span>
<!--
Too bad the menu has to be inside of the button
but hey, it's pure CSS magic.
-->
<ul id="menu">
<a href="index.html" target="_blank"><li>Home</li></a>
<a href="blog.html" target="_blank"><li>Blog</li></a>
<a href="preface.html" target="_blank"><li>Preface</li></a>
<a href="preliminaries.html" target="_blank"><li>Rabbit Holes</li></a>
<li>Numbers</li>
<ul>
<a href="numbers1.html" target="_blank"><li>Numbers 1</li></a>
<a href="numbers2.html" target="_blank"><li>Numbers 2</li></a>
</ul>
</ul>
</div>
</nav>
</div>
</p>
<div id="outline-container-orga331ba1" class="outline-2">
<h2 id="orga331ba1">Getting started</h2>
</div>
<div id="outline-container-org1afe6ab" class="outline-2">
<h2 id="org1afe6ab">Monday at the library</h2>
<div class="outline-text-2" id="text-org1afe6ab">
<p>
It’s a Monday morning in late July and the von der Surwitz siblings
meet in a reserved study room at the main university library to go
over what their <i>Introduction to Computer Science</i> teacher, Professor
Chandra, had discussed with them at Novalis Tech Open House.
</p>
<p>
Checking Professor Chandra’s course syllabus on her website before,
they had already made online purchases of the two main texts for the
course, <i>The Haskell Road to Logic, Maths and Programming</i> by Kees
Doets and Jan van Eijck, as well as <i>Thinking as Computation</i> from
Hector Levesque. During the open house at the convention wing of the
student center on the previous Saturday, they had sat around a table
with the professor as she paged through the texts and talked
extemporaneously about what parts she would handle and how. She also
showed them some code on her laptop. She invited them to email her
with any questions.
</p>
<p>
The professor encouraged them to dive into to the logic and sets
prereqs, alongside of the first few chapters of <i>The Haskell Road…</i>,
as well as to get through as much <i>Learn You a Haskell…</i> as
possible.
</p>
<p>
Ursula von der Surwitz has plugged in her laptop to the big monitor
and is scrolling through some of her personal notes.
</p>
<p>
<span class="fraktur">ππ―π°π²π©π:</span> So like
Professor Chandra said on Saturday, eventually everything we’re doing
will be in terms of logic and set theory. <br />
[murmurs of agreement and then silence] <br />
<span class="fraktur">ππ―π°π²π©π:</span> [continuing] It
seems a bit ominous. <br />
<span class="fraktur">ππ΄π’:</span> Out with the old
math, in with the new. <br />
[nods and agreement] <br />
<span class="fraktur">ππ±π’::</span> But like she was
saying, comp-sci math is sort of a “grab-bag” of higher math, that is,
the stuff you’d be learning after all the calculus and differential
equations and linear algebra. <br />
[murmurs of agreement] <br />
<span class="fraktur">ππ΄π’:</span> Like the examples
she gave, using set theory we can properly define relations and
functions. <br />
[more agreement murmurs] <br />
<span class="fraktur">ππ±π’:</span> I’m psyched. <br />
[more agreement murmurs] <br />
<span class="fraktur">ππ±π’:</span> [continuing] I’m
psyched because — as she said — this course is totally
experimental and open-ended. She’s basically going to give us what
she’d be giving her college freshman and sophomores in the CS
department. And she’s giving us her total undivided attention.<br />
<span class="fraktur">ππ΄π’:</span> It’s only us, her
daughter — and maybe three others who weren’t there and might not
take it. Exactly. She’s on sabbatical; no other duties. Wow. This is
completely unique.<br />
<span class="fraktur">ππ±π’:</span> Bottom line: We’ve
got a once-in-a-lifetime chance to really learn a ton about
comp-sci. Like I say, I’m psyched! <br />
<span class="fraktur">ππ΄π’:</span> All we have to do
is hang on for dear life. <br />
[laughter] <br />
<span class="fraktur">ππ―π°π²π©π:</span> [paging through
<i>Haskell Road…</i> ] Did anyone look at the first chapter? <br />
[affirmative nods] <br />
<span class="fraktur">ππ―π°π²π©π:</span> [continuing]
Wasn’t too bad — once I caught on to what he was saying. But I have
to say, the <i>Learn You a Haskell…</i> helped. <br />
[murmurs of agreement] <br />
<span class="fraktur">ππ±π’:</span> I think it’s cool
how the whole prime number test, the greatest common divisor all
blended together. <br />
<span class="fraktur">ππ΄π’:</span> But I’m glad I’d
seen the prime factorization way of figuring out unlike-denominator
math back in Kiel. <i>If</i> I can remember it. <br />
[affirmative murmurs] <br />
<span class="fraktur">ππ±π’:</span> Oh, by the way,
does anyone remember why the Greeks said, for example, \(7\) <i>measures</i>
\(35\;\)? <br />
<span class="fraktur">ππ―π°π²π©π:</span> Wasn’t that
because a rod or measuring tape that’s \(7\) units long can then measure
out a length of \(35\) perfectly? <br />
[murmurs of agreement] <br />
<span class="fraktur">ππ―π°π²π©π:</span> Well, I
remember prime factorization was based on the <a href="https://en.wikipedia.org/wiki/Fundamental_theorem_of_arithmetic">Fundamental Theorem of
Arithmetic</a> from dear old Euclid. [bringing up the Wikipedia article
in both English and German, reading from the English page] <i>If a prime
\(p\) divides the product \(a \cdot b\), then \(p\) divides either \(a\) or \(b\) or
both</i>. And that really means [reading on] <i>Every positive integer \(n >
1\) can be represented in exactly one way as a product of prime
powers</i>. Got that? [pulling an ironic face] Do you see how the first
and second statements are equivalent? <br />
<span class="fraktur">ππ΄π’:</span> [also ironically]
Oh sure, of course. <br />
[laughter] <br />
<span class="fraktur">ππ―π°π²π©π:</span> And here’s the
proof. [half-mumbling the German page’s proof] It’s a contradiction
proof. Our favorite. <br />
[laughter] <br />
<span class="fraktur">ππ΄π’:</span> Oh, right. That’s
where you take off at top speed at a brick wall, smash into brick
wall, die … and that proves you should have gone exactly the
opposite direction. <br />
[laughter] <br />
<span class="fraktur">ππ±π’:</span> Wasn’t it amazing
how Professor Chandra just put two fractions with huge unlike
denominators into the Racket command line<label for="1" class="margin-toggle sidenote-number"></label><input type="checkbox" id="1" class="margin-toggle"/><span class="sidenote">
Professor Chandra has demonstrated at the Racket command line
how rationals could be directly added, e.g., <br />
<code>> (+ 1/32 1/943720)</code> <br />
and get back <br />
<code>117969/3774880</code>
</span>. Did anybody besides
me install it? <br />
[affirmative murmurs] <br />
<span class="fraktur">ππ―π°π²π©π:</span> [bringing up
Racket in a terminal] Here, I’ll just try something. [typing] <br />
</p>
<pre class="example" id="org336e0e4">
> (+ 1/15 1/85)
4/51
</pre>
<p>
<span class="fraktur">ππ±π’:</span> I see you learned
the prefix way of doing Racket. <br />
[Ursula nods.] <br />
<span class="fraktur">ππ±π’:</span> [going to the
whiteboard] I’ll put the prime factorization method down just to
refresh my memory. [writing] So \(15\) is multiplying prime numbers \(3\)
and \(5\), and \(85\) is multiplying primes \(5\) and \(17\) together. Now
we’ve got the primes. I’ll make a table of them
</p>
<table border="2" cellspacing="0" cellpadding="6" rules="all" frame="border">
<caption class="t-bottom"><span class="table-number">Table 1:</span> 15 factored into its primes</caption>
<colgroup>
<col class="org-left" />
<col class="org-left" />
<col class="org-right" />
<col class="org-right" />
</colgroup>
<thead>
<tr>
<th scope="col" class="org-left">\(\quad\) 15 \(\quad\)</th>
<th scope="col" class="org-left">\(\quad\) 2 \(\quad\)</th>
<th scope="col" class="org-right">\(\quad\) 3 \(\quad\)</th>
<th scope="col" class="org-right">\(\quad\) 5 \(\quad\)</th>
</tr>
</thead>
<tbody>
<tr>
<td class="org-left"> </td>
<td class="org-left"> </td>
<td class="org-right">1</td>
<td class="org-right">1</td>
</tr>
</tbody>
</table>
<table border="2" cellspacing="0" cellpadding="6" rules="all" frame="border">
<caption class="t-bottom"><span class="table-number">Table 2:</span> 85 factored into its primes</caption>
<colgroup>
<col class="org-left" />
<col class="org-left" />
<col class="org-left" />
<col class="org-right" />
<col class="org-left" />
<col class="org-left" />
<col class="org-left" />
<col class="org-right" />
</colgroup>
<thead>
<tr>
<th scope="col" class="org-left">\(\quad\) 85 \(\quad\)</th>
<th scope="col" class="org-left">\(\;\) 2 \(\;\)</th>
<th scope="col" class="org-left">\(\;\) 3 \(\;\)</th>
<th scope="col" class="org-right">\(\;\) 5 \(\;\)</th>
<th scope="col" class="org-left">\(\;\) 7 \(\;\)</th>
<th scope="col" class="org-left">\(\;\) 11 \(\;\)</th>
<th scope="col" class="org-left">\(\;\) 13 \(\;\)</th>
<th scope="col" class="org-right">\(\;\) 17 \(\;\)</th>
</tr>
</thead>
<tbody>
<tr>
<td class="org-left"> </td>
<td class="org-left"> </td>
<td class="org-left"> </td>
<td class="org-right">1</td>
<td class="org-left"> </td>
<td class="org-left"> </td>
<td class="org-left"> </td>
<td class="org-right">1</td>
</tr>
</tbody>
</table>
<p>
<span class="fraktur">ππ±π’:</span> [continuing] So we
take the unique primes in common between the two denominators — that
would be \(3\;\), \(5\;\), and \(17\:\) and multiply them together to
get… <br />
<span class="fraktur">ππ―π°π²π©π:</span> [typing into
Racket] That gives us \(255\;\). <br />
<span class="fraktur">ππ±π’:</span> So now \(255\) will
be the common denominator. But we have to calculate the ratios
[writing] <br />
</p>
\begin{align*}
\frac{1}{15} &= \frac{x}{255} \\[.5em]
\frac{1}{85} &= \frac{y}{255}
\end{align*}
<p>
<span class="fraktur">ππ―π°π²π©π:</span> [tabbing over
to her org-mode buffer] Here, let me write a little Haskell function
for that, a proverbial one-liner doing — <i>Dreisatz</i>? What’s
<i>Dreisatz?</i> <br />
<span class="fraktur">ππ±π’:</span> Ah, literally
<i>rule of three.</i> <br />
<span class="fraktur">ππ―π°π²π©π:</span> [Ursula looks
it up on Wikipedia] Or just <i>cross-multiplication</i>. [typing into a
org-mode Babel source block] <br />
</p>
<pre class="code"><code><span class="org-haskell-definition">crossMult</span> <span class="org-haskell-operator">=</span> <span class="org-haskell-operator">\</span>a b d <span class="org-haskell-operator">-></span> <span class="org-rainbow-delimiters-depth-1">(</span><span class="org-rainbow-delimiters-depth-2">(</span>a <span class="org-haskell-operator">*</span> d<span class="org-rainbow-delimiters-depth-2">)</span> <span class="org-haskell-operator">/</span> b<span class="org-rainbow-delimiters-depth-1">)</span> <span class="org-comment-delimiter">-- </span><span class="org-comment">a/b = x/d ... solve for unknown</span>
</code></pre>
<p>
[running it with parameters] <br />
</p>
<pre class="code"><code><span class="org-haskell-definition">crossMult</span> 1 15 255
</code></pre>
<pre class="example">
17.0
</pre>
<p>
<span class="fraktur">ππ΄π’:</span> So you’re doing an
anonymous function<label for="2" class="margin-toggle sidenote-number"></label><input type="checkbox" id="2" class="margin-toggle"/><span class="sidenote">
Check out anonymous or <i>lambda</i> functions <a href="http://learnyouahaskell.com/higher-order-functions#lambdas">here</a>.
</span>, right? <br />
<span class="fraktur">ππ―π°π²π©π:</span> Right. Yeah,
pretty neat, huh? <br />
<span class="fraktur">ππ΄π’:</span> And you’re not
worrying about doing a type declaration. <br />
<span class="fraktur">ππ―π°π²π©π:</span> Not really. I
could. But I’m just letting Haskell figure it out. I’ll get the <i>type</i>
with <code>:t</code> [typing at the REPL]
</p>
<pre class="code"><code><span class="org-haskell-constructor">:</span>t crossMult
</code></pre>
<pre class="example">
crossMult :: Double -> Double -> Double -> Double
</pre>
<p>
<span class="fraktur">ππ―π°π²π©π:</span> [continuing]
Actually, I could have done it this way [typing in new source block]
</p>
<pre class="code"><code><span class="org-haskell-constructor">:</span><span class="org-rainbow-delimiters-depth-1">{</span>
<span class="org-haskell-definition">crossMult2</span> <span class="org-haskell-operator">::</span> <span class="org-haskell-type">Integer</span> <span class="org-haskell-operator">-></span> <span class="org-haskell-type">Integer</span> <span class="org-haskell-operator">-></span> <span class="org-haskell-type">Integer</span> <span class="org-haskell-operator">-></span> <span class="org-haskell-type">Integer</span>
<span class="org-haskell-definition">crossMult2</span> <span class="org-haskell-operator">=</span> <span class="org-haskell-operator">\</span>a b d <span class="org-haskell-operator">-></span> <span class="org-rainbow-delimiters-depth-2">(</span><span class="org-rainbow-delimiters-depth-3">(</span>a <span class="org-haskell-operator">*</span> d<span class="org-rainbow-delimiters-depth-3">)</span> <span class="org-haskell-operator">`div`</span> b<span class="org-rainbow-delimiters-depth-2">)</span>
<span class="org-haskell-constructor">:</span><span class="org-rainbow-delimiters-depth-1">}</span>
</code></pre>
<pre class="code"><code><span class="org-haskell-definition">crossMult2</span> 1 85 255
</code></pre>
<pre class="example">
3
</pre>
<p>
<span class="fraktur">ππ±π’:</span> So you
specifically declared the type signature for your <code>crossMult2</code>. And it
you specifically made it just <code>Integer</code> parameters producing an
<code>Integer</code> answer. But then you’re using <code>div</code>? Why then? <br />
<span class="fraktur">ππ―π°π²π©π:</span> Watch
this. [typing into REPL] I’ll get some information on regular division
<code>/</code> versus <code>div</code>.
</p>
<pre class="code"><code><span class="org-haskell-constructor">:</span>t <span class="org-rainbow-delimiters-depth-1">(</span><span class="org-haskell-operator">/</span><span class="org-rainbow-delimiters-depth-1">)</span>
</code></pre>
<pre class="example">
(/) :: Fractional a => a -> a -> a
</pre>
<pre class="code"><code><span class="org-haskell-constructor">:</span>i <span class="org-rainbow-delimiters-depth-1">(</span><span class="org-haskell-operator">/</span><span class="org-rainbow-delimiters-depth-1">)</span>
</code></pre>
<pre class="example">
type Fractional :: * -> Constraint
class Num a => Fractional a where
(/) :: a -> a -> a
...
-- Defined in βGHC.Realβ
infixl 7 /
</pre>
<pre class="code"><code><span class="org-haskell-constructor">:</span>t div
</code></pre>
<pre class="example">
div :: Integral a => a -> a -> a
</pre>
<p>
<span class="fraktur">ππ΄π’:</span> Wow. Still getting
used to reading that stuff. <br />
[laughter] <br />
<span class="fraktur">ππ±π’:</span> All right, so I’m
assuming they’re calling the one type class [writing on the board]
<code>Fractional</code> because that means literally something that’s numerical
and not a whole number. And then the other [writing] <code>Integral</code> is
something related to an integer whole number. So basically, a type
class adds a property or trait to types. It’s starting to get clearer
— maybe. <br />
[murmurs of agreement] <br />
<span class="fraktur">ππ―π°π²π©π:</span> Let me go to a
link on <a href="https://stackoverflow.com/questions/35950600/why-it-is-impossible-to-divide-integer-number-in-haskell">stackoverflow</a> that talks about this<label for="3" class="margin-toggle sidenote-number"></label><input type="checkbox" id="3" class="margin-toggle"/><span class="sidenote">
See <a href="https://stackoverflow.com/questions/35950600/why-it-is-impossible-to-divide-integer-number-in-haskell">Why it is impossible to divide Integer number in Haskell?</a>
</span>. Getting
there… [displays post on monitor] Right. So the original post has
this and wonders why the error
</p>
<pre class="code"><code><span class="org-rainbow-delimiters-depth-1">(</span>4 <span class="org-haskell-operator">::</span> <span class="org-haskell-type">Integer</span><span class="org-rainbow-delimiters-depth-1">)</span> <span class="org-haskell-operator">/</span> 2
</code></pre>
<pre class="example" id="org4ae7502">
<interactive>:36:16: error:
β’ No instance for (Fractional Integer) arising from a use of β/β
β’ In the expression: (4 :: Integer) / 2
In an equation for βitβ: it = (4 :: Integer) / 2
</pre>
<p>
<span class="fraktur">ππ±π’:</span> I’m guessing it’s
saying you can’t do a regular <i>fractional</i> divide because you’ve
specifically said this is an integer, right? <br />
<span class="fraktur">ππ―π°π²π©π:</span> [getting up and
pointing on the monitor] Basically, yes. There’s a type class called
<code>Fractional</code> and it’s saying that when we specifically make <code>4</code> an
<code>Integer</code> this way [writing on the board] <code>(4 :: Integer)</code>, that makes
it ineligible for doing regular <i>fractional</i> division. <br />
<span class="fraktur">ππ΄π’:</span> And that’s because
the type and class system behind all this doesn’t allow it. <br />
<span class="fraktur">ππ―π°π²π©π:</span> Yes, as far as
I can tell. Did you get through the <i>Learn You…</i> part on type
classes<label for="4" class="margin-toggle sidenote-number"></label><input type="checkbox" id="4" class="margin-toggle"/><span class="sidenote">
See <a href="http://learnyouahaskell.com/types-and-typeclasses#typeclasses-101">Typeclasses 101</a> in <i>Learn You a Haskell…</i>.
</span>? <br />
<span class="fraktur">ππ΄π’:</span> Yes, but… <br />
[laughter] <br />
<span class="fraktur">ππ―π°π²π©π:</span> I emailed the
professor about this and she said she’d soon go over it in detail. <br />
[murmurs of acknowledgement] <br />
<span class="fraktur">ππ―π°π²π©π:</span> [continuing]
The bottom line — as someone is saying in the comments — is that
<i>integer</i> division not the same as <i>fractional</i> division. <br />
<span class="fraktur">ππ΄π’:</span> This type and
class stuff is why [pointing at the monitor] <code>4 / 2</code> works and this
<code>(4 :: Integer) / 2</code> thing doesn’t. <br />
<span class="fraktur">ππ―π°π²π©π:</span> [typing into
the ghci REPL] Here, see?
</p>
<pre class="code"><code>4 <span class="org-haskell-operator">/</span> 2
</code></pre>
<pre class="example">
2.0
</pre>
<p>
<span class="fraktur">ππ―π°π²π©π:</span> It knows how to
pretend it’s not integer division. It goes ahead and gives you back a
decimal number. <br />
[group studies the examples] <br />
<span class="fraktur">ππ―π°π²π©π:</span> In her email
the professor said we shouldn’t think of literal numbers like
[pointing] <code>4</code> and <code>2</code> as any sort of definite type just by itself
[typing into REPL]
</p>
<pre class="code"><code><span class="org-haskell-constructor">:</span>t 1
</code></pre>
<pre class="example">
1 :: Num p => p
</pre>
<p>
<span class="fraktur">ππ―π°π²π©π:</span> What this is
saying is that <code>1</code> is <i>any</i> number — until you commit to using it in
a certain way. <br />
<span class="fraktur">ππ±π’:</span> So we need to use
<code>div</code> if we specifically want integer division. <br />
<span class="fraktur">ππ―π°π²π©π:</span> Exactly [typing
into REPL]
</p>
<pre class="code"><code><span class="org-rainbow-delimiters-depth-1">(</span>5 <span class="org-haskell-operator">`div`</span> 2<span class="org-rainbow-delimiters-depth-1">)</span>
</code></pre>
<pre class="example">
2
</pre>
<p>
<span class="fraktur">ππ―π°π²π©π:</span> See? It’s
rounding down and throwing away the remainder just like it should with
whole numbers [typing into REPL]
</p>
<pre class="code"><code>5 <span class="org-haskell-operator">/</span> 2
</code></pre>
<pre class="example">
2.5
</pre>
<pre class="code"><code><span class="org-haskell-constructor">:</span>t <span class="org-rainbow-delimiters-depth-1">(</span>5 <span class="org-haskell-operator">/</span> 2<span class="org-rainbow-delimiters-depth-1">)</span>
</code></pre>
<pre class="example">
(5 / 2) :: Fractional a => a
</pre>
<pre class="code"><code><span class="org-haskell-constructor">:</span>t <span class="org-rainbow-delimiters-depth-1">(</span>5 <span class="org-haskell-operator">`div`</span> 2<span class="org-rainbow-delimiters-depth-1">)</span>
</code></pre>
<pre class="example">
(5 `div` 2) :: Integral a => a
</pre>
<p>
<span class="fraktur">ππ΄π’:</span> Good. I think I’ve
got it — in a shaky sort of way. <br />
[silence] <br />
<span class="fraktur">ππ―π°π²π©π:</span> So back to the
lowest common denominator thing… <br />
[laughter] <br />
<span class="fraktur">ππ―π°π²π©π:</span> [continuing]
\(17\:\) is the amount the numerator of the original \(1/15\) has to be
multiplied by to be equivalent using the new denominator \(255\:\). So
now \(1/15\) <i>is equivalent to</i> \(17/255\;\). Next up, for \(1/85\:\) we’ve
got
</p>
<pre class="code"><code><span class="org-haskell-definition">crossMult</span> 1 85 255
</code></pre>
<pre class="example">
3.0
</pre>
<p>
<span class="fraktur">ππ±π’:</span> [continuing on the
board] That means \(1/85\:\) is equivalent to \(3/255\:\), and then adding
gives us
</p>
\begin{align*}
\frac{17}{255} + \frac{3}{255} = \frac{20}{255}
\end{align*}
<p>
<span class="fraktur">ππ±π’:</span> [continuing] So we
can reduce this by factoring out \(5\)
</p>
\begin{align*}
\require{cancel}
\frac{\cancel{5} \cdot 4}{\cancel{5} \cdot 51} \\
\end{align*}
<p>
<span class="fraktur">ππ΄π’:</span> Wait. I think
we’re doing this wrong. We shouldn’t need to factor out the \(5\;\),
right? So the common denominator should have been just the prime \(3\)
times the prime \(17\) because the prime \(5\) should have been left
out. Both \(15\) and \(85\) just have one \(5\) each as a factor. So if they
both have \(5\) let’s just leave it out.<br />
[silence] <br />
<span class="fraktur">ππ΄π’:</span> [continuing] So
those tables, Ute, maybe we can just subtract one table from the other
and go with whatever’s left? <br />
<span class="fraktur">ππ―π°π²π©π:</span> [typing
calculations into the Racket command line] Not sure about that, dear
brother. My gut tells me — and my memory too — that no, it’s not
that simple. So, just for sake of argument, if they have a common
prime factor then let’s leave it out … <i>if</i> they’re the same
exponentially. So we had both denominators with the prime factor
\(5^{1}\:\). Good. We drop it. But then what if they share a prime factor
but different exponentiations of it? What then? <br />
<span class="fraktur">ππ΄π’:</span> Explain,
please. <br />
<span class="fraktur">ππ―π°π²π©π:</span> [typing into
Racket’s REPL] So first, here’s a contrived example where I know both
have \(2^{2}\)
</p>
<pre class="example" id="org808238d">
> (+ 1/20 1/28)
3/35
</pre>
<p>
<span class="fraktur">ππ―π°π²π©π:</span> [continuing] So
\(20\) is \(2^{2}\) times \(5\:\), and \(28\) is that same \(2^{2}\) times \(7\;\). So
yes, we’ll get rid of the \(2^{2}\) — they’re the same prime factor
raised to the same exponent — and we just multiply the \(5\) and the
\(7\) to get \(35\:\), which is the denominator \(35\;\). And the answer
Racket gives us, \(3/35\;\), is in simplest form, so we know it’s
right. <i>But</i>, let me try an example where there’s a prime to a power
in one denominator and the same prime <i>to a higher power</i> in the other
[she does calculations on a sheet of paper, then types into the
command line]
</p>
<pre class="example" id="org9f1e9db">
> (+ 1/88 1/80)
21/880
</pre>
<p>
<span class="fraktur">ππ―π°π²π©π:</span> [continuing] So
I’ve put together a situation where \(80\) is \(2^{4}\) times \(5\;\), and \(88\)
is \(2^{3}\) times \(11\;\). And here we see \(880\:\) is the smallest
denominator possible. And \(21/880\;\) is in simplest form, so there’s
no factoring out to get it into simpler terms. And yes, \(2^{4}\) times \(5\)
times \(11\) went into making \(880\;\). <br />
<span class="fraktur">ππ΄π’:</span> Yeah, I see. The
\(2^{4}\) did have to go into it. And it was the \(2\) with the higher
exponent. So when I said subtract one table from the other I guess I
was implying we could do exponent subtraction, like \(2^{4-3}\:\), get just
the \(2\) and then make up a denominator out of \(2 \cdot 5 \cdot 11\) which would
<i>not</i> have worked. Hey, should we try to write a Haskell function to
check all this? <br />
<span class="fraktur">ππ±π’:</span> Hold that thought,
not yet. And I say that because <i>The Haskell Road…</i> has a way we
should learn. I looked at it. <br />
<span class="fraktur">ππ―π°π²π©π:</span> Well, I asked
Mutti about this — and she said we should look into the <i>least
common multiple</i>, because that’s what this lowest common denominator
issue is all about. And yes, I knew that but had forgotten. So here’s
the Wikipedia article on it<label for="5" class="margin-toggle sidenote-number"></label><input type="checkbox" id="5" class="margin-toggle"/><span class="sidenote">
See the article <a href="https://en.wikipedia.org/wiki/Least_common_multiple">here</a>.
</span>. [displays page on monitor] <br />
<span class="fraktur">ππ΄π’:</span> [mumbling the
first sentence<label for="6" class="margin-toggle sidenote-number"></label><input type="checkbox" id="6" class="margin-toggle"/><span class="sidenote">
<font color = "#0d3db3">…In arithmetic and number
theory, the <i>least common multiple</i>, <i>lowest common multiple</i>, or
<i>smallest common multiple</i> of two integers \(a\) and \(b\:\), usually
denoted by \(lcm(a, b)\:\), is the smallest positive integer that is
divisible by both \(a\) and \(b\;\)…</font>
</span>] You’re right. I knew this but had lost track of
it. <br />
<span class="fraktur">ππ±π’:</span> Which means we
<i>don’t</i> want to kick out <i>any</i> primes with the same exponent just
because the denominators share them. <br />
[embarrassed laughter] <br />
<span class="fraktur">ππ―π°π²π©π:</span> [typing into
the Racket REPL] So trying \(20\) and \(28\) as denominators again, we
thought \(35\) was the common denominator for all situations. But watch,
I’ll put in some different numerators
</p>
<pre class="example" id="org1b76df7">
> (+ 5/20 11/28)
9/14
> (+ 1/20 11/28)
31/70
> (+ 3/20 13/28)
43/70
</pre>
<p>
[laughter] <br />
<span class="fraktur">ππ΄π’:</span> Oops. My bad. That
was a complete fluke factoring out the \(2^{2}\) and just calling the
lowest common denominator \(5\) times \(7\:\). So the real lowest common
multiple, the smallest number that both \(20\) and \(28\) evenly divide
into is, in fact, \(2^{2}\) times \(5\) times \(7\;\), which is \(140\;\). <br />
<span class="fraktur">ππ―π°π²π©π:</span> Now, let’s get
the numerators [typing]
</p>
<pre class="code"><code><span class="org-haskell-definition">crossMult</span> 5 20 140
</code></pre>
<pre class="example">
35.0
</pre>
<pre class="code"><code><span class="org-haskell-definition">crossMult</span> 11 28 140
</code></pre>
<pre class="example">
55.0
</pre>
<p>
<span class="fraktur">ππ±π’:</span> [writing on the
board] So this is what we have
</p>
\begin{align*}
\frac{35}{140} + \frac{55}{140} = \frac{90}{140} = \frac{9}{14}
\end{align*}
<p>
and no \(35\) in sight. <br />
<span class="fraktur">ππ΄π’:</span> Got it. <br />
[silence as they all read further into the article] <br />
<span class="fraktur">ππ―π°π²π©π:</span> So yes, now I
think we should try what they’re saying where you list out multiples
of the two denominators until you find the first common
multiple. Let’s try it as a Haskell program. <br />
[agreement murmurs] <br />
<span class="fraktur">ππ―π°π²π©π:</span> [making a new
org-mode source block] Okay, so we’re basically talking about an
<i>arithmetic series</i> where a sequence of numbers increases or decreases
at a fixed amount. In this case the series will increase by the amount
of the denominators at each step. So let me do this [typing]
</p>
<pre class="code"><code><span class="org-haskell-constructor">:</span><span class="org-rainbow-delimiters-depth-1">{</span>
<span class="org-haskell-definition">myLCM</span> dnom1 dnom2
<span class="org-haskell-operator">=</span> take 1 <span class="org-rainbow-delimiters-depth-2">[</span><span class="org-rainbow-delimiters-depth-3">(</span><span class="org-rainbow-delimiters-depth-4">(</span><span class="org-haskell-operator">*</span>dnom1<span class="org-rainbow-delimiters-depth-4">)</span>x<span class="org-rainbow-delimiters-depth-3">)</span> <span class="org-haskell-operator">|</span> x <span class="org-haskell-operator"><-</span> <span class="org-rainbow-delimiters-depth-3">[</span>1<span class="org-haskell-operator">..</span>200<span class="org-rainbow-delimiters-depth-3">]</span>,
y <span class="org-haskell-operator"><-</span> <span class="org-rainbow-delimiters-depth-3">[</span>1<span class="org-haskell-operator">..</span>200<span class="org-rainbow-delimiters-depth-3">]</span>,
<span class="org-rainbow-delimiters-depth-3">(</span><span class="org-rainbow-delimiters-depth-4">(</span><span class="org-haskell-operator">*</span>dnom1<span class="org-rainbow-delimiters-depth-4">)</span>x <span class="org-haskell-operator">==</span> <span class="org-rainbow-delimiters-depth-4">(</span><span class="org-haskell-operator">*</span>dnom2<span class="org-rainbow-delimiters-depth-4">)</span>y<span class="org-rainbow-delimiters-depth-3">)</span> <span class="org-rainbow-delimiters-depth-2">]</span>
<span class="org-haskell-constructor">:</span><span class="org-rainbow-delimiters-depth-1">}</span>
</code></pre>
<p>
<span class="fraktur">ππ―π°π²π©π:</span> [continuing]
Now for denominators \(15\) and \(85\) like before
</p>
<pre class="code"><code><span class="org-haskell-definition">myLCM</span> 15 85
</code></pre>
<pre class="example">
[255]
</pre>
<p>
<span class="fraktur">ππ―π°π²π©π:</span> [continuing] So
it works. But I don’t think it’s good for really big
denominators. This is strictly proof of concept. <br />
[Uwe and Ute study the code] <br />
<span class="fraktur">ππ΄π’:</span> Again, wow. But
you lost me on the <code>(*dnom1)</code> and <code>(*dnom2)</code>. What’s going on there?
<br />
<span class="fraktur">ππ―π°π²π©π:</span> That’s what
they call a <i>section</i>. I got that the other day from <i>A Gentle
Introduction to Haskell</i><label for="7" class="margin-toggle sidenote-number"></label><input type="checkbox" id="7" class="margin-toggle"/><span class="sidenote">
Available <a href="https://www.haskell.org/tutorial/">here</a>. The page dealing with <i>sections</i> is <a href="https://www.haskell.org/tutorial/functions.html">here</a> in
3.2.1. Also The <a href="https://wiki.haskell.org/Section_of_an_infix_operator">wiki.haskell.org</a> has a page on sections as well.
</span>. Basically, <code>*dnom1</code> is made into a
function that takes whatever <code>dnom1</code> is and applies it just as if it
were a function to the <code>x</code>. So <code>(*dnom1)x</code> is the same as just <code>x *
dnom1</code>. Here’s an example [typing into the ghci REPL]
</p>
<pre class="code"><code><span class="org-rainbow-delimiters-depth-1">(</span><span class="org-haskell-operator">*</span>2<span class="org-rainbow-delimiters-depth-1">)</span>5 <span class="org-haskell-operator">==</span> <span class="org-rainbow-delimiters-depth-1">(</span>2<span class="org-haskell-operator">*</span><span class="org-rainbow-delimiters-depth-1">)</span>5
</code></pre>
<pre class="example">
True
</pre>
<p>
<span class="fraktur">ππ―π°π²π©π:</span> [continuing]
Since multiplication is commutative, the <code>*</code> sign can be in front of
the multiplicand or behind it. But that’s not always the case. For
example [typing]
</p>
<pre class="code"><code><span class="org-rainbow-delimiters-depth-1">(</span>2<span class="org-haskell-operator">^</span><span class="org-rainbow-delimiters-depth-1">)</span>3
</code></pre>
<pre class="example">
8
</pre>
<pre class="code"><code><span class="org-rainbow-delimiters-depth-1">(</span><span class="org-haskell-operator">^</span>2<span class="org-rainbow-delimiters-depth-1">)</span>3
</code></pre>
<pre class="example">
9
</pre>
<p>
<span class="fraktur">ππ―π°π²π©π:</span> [continuing] So
the second one <i>flips</i> the \(3\) to the other side. Not to get too far
down this rabbit hole, I could write something like this [typing]
</p>
<pre class="code"><code><span class="org-haskell-definition">myTimesTwo</span> <span class="org-haskell-operator">=</span> <span class="org-rainbow-delimiters-depth-1">(</span><span class="org-haskell-operator">*</span>2<span class="org-rainbow-delimiters-depth-1">)</span>
</code></pre>
<pre class="code"><code><span class="org-haskell-definition">myTimesTwo</span> 5
</code></pre>
<pre class="example">
10
</pre>
<p>
<span class="fraktur">ππ΄π’:</span> Okay, I get
it. Impressive. <br />
<span class="fraktur">ππ―π°π²π©π:</span> So here’s one
more cool thing about sections. Look at this and try to guess what it
does [typing into a source block]
</p>
<pre class="code"><code><span class="org-haskell-definition">myListOfAddFuncs</span> <span class="org-haskell-operator">=</span> map <span class="org-rainbow-delimiters-depth-1">(</span><span class="org-haskell-operator">+</span><span class="org-rainbow-delimiters-depth-1">)</span> <span class="org-rainbow-delimiters-depth-1">[</span>1,2,3<span class="org-rainbow-delimiters-depth-1">]</span>
</code></pre>
<p>
<span class="fraktur">ππ±π’:</span> Aaah, not
sure. Give us a hint. <br />
<span class="fraktur">ππ―π°π²π©π:</span> Right, so
according to <i>The Gentle Introduction…</i> we’ve got [writing on the
board]
</p>
<pre class="example" id="org4f139e8">
(+) = \x y -> x + y
</pre>
<p>
<span class="fraktur">ππ±π’:</span> So with sections
the operator and whatever variable you include has to be in
parentheses, right? <br />
<span class="fraktur">ππ―π°π²π©π:</span> Yes. We’re
packaging up a common operator like plus or times, and maybe a
variable, to work as a function. <br />
<span class="fraktur">ππ΄π’:</span> <i>Luft von anderem
Planeten</i><label for="8" class="margin-toggle sidenote-number"></label><input type="checkbox" id="8" class="margin-toggle"/><span class="sidenote">
A famous line from a Stefan Georg poem: <i>Ich fΓΌhle Luft von
anderem Planeten</i> or <i>I feel (the) air of (the other) another planet.</i>
</span> <br />
[laughter] <br />
<span class="fraktur">ππ΄π’:</span> [continuing] No,
really, I barely understand that anonymous stuff, but I hear you
saying <code>myListOfAddFuncs</code> could have been written with an anonymous
function [writes on the board]
</p>
<pre class="code"><code><span class="org-haskell-definition">myLOAF</span> <span class="org-haskell-operator">=</span> map <span class="org-rainbow-delimiters-depth-1">(</span><span class="org-haskell-operator">\</span>x y <span class="org-haskell-operator">-></span> x <span class="org-haskell-operator">+</span> y<span class="org-rainbow-delimiters-depth-1">)</span> <span class="org-rainbow-delimiters-depth-1">[</span>1,2,3<span class="org-rainbow-delimiters-depth-1">]</span>
</code></pre>
<p>
<span class="fraktur">ππ΄π’:</span> [continuing] And
I’m guessing that this creates a <i>list of functions</i> like [writing]
</p>
<pre class="example" id="org6017c39">
[(1+),(2+),(3+)]
</pre>
<p>
<span class="fraktur">ππ―π°π²π©π:</span> So let’s just
test it [typing]
</p>
<pre class="code"><code><span class="org-haskell-definition">map</span> <span class="org-rainbow-delimiters-depth-1">(</span>myListOfAddFuncs <span class="org-haskell-operator">!!</span> 2<span class="org-rainbow-delimiters-depth-1">)</span> <span class="org-rainbow-delimiters-depth-1">[</span>1,2,3<span class="org-rainbow-delimiters-depth-1">]</span>
</code></pre>
<pre class="example">
[4,5,6]
</pre>
<p>
<span class="fraktur">ππ±π’:</span> Again, I just
barely understand all these components. I sort of understand <code>map</code>. I
sort of understand what you’re doing with sections, as they’re
called. I sort of understand what Brother just said. So I’m going to
guess that you have the list of functions in the form of sections, and
you just told it to apply this list of functions to the list
<code>[1,2,3]</code>. <br />
<span class="fraktur">ππ―π°π²π©π:</span> Not
exactly. I’m still trying to figure that one out. No, what I’m doing
is using the Haskell index operator <code>!!</code> to say “give me the third
element,” which is the function <code>(3+)</code>. Even though it says <code>2</code>, the
index starts at <code>0</code>, so the third function in <code>myListOfAddFuncs</code> is
<code>(3+)</code> and <code>map</code> then applies it across <code>[1,2,3]</code> giving <code>[4,5,6]</code>
since it adds <code>3</code> to each element of the input list. See? <br />
[nods and murmurs of agreement] <br />
<span class="fraktur">ππ΄π’:</span> So back to the —
list comprehension? Is that what it’s called? <br />
<span class="fraktur">ππ―π°π²π©π:</span> Right
[scrolling back]
</p>
<pre class="example" id="orgf684eeb">
myLCM dnom1 dnom2
= take 1 [((*dnom1)x) | x <- [1..200],
y <- [1..200],
((*dnom1)x == (*dnom2)y) ]
</pre>
<pre class="code"><code><span class="org-haskell-definition">myLCM</span> 15 85
</code></pre>
<pre class="example">
[255]
</pre>
<p>
<span class="fraktur">ππ―π°π²π©π:</span> So this is a
<i>list comprehension</i><label for="9" class="margin-toggle sidenote-number"></label><input type="checkbox" id="9" class="margin-toggle"/><span class="sidenote">
See <a href="http://learnyouahaskell.com/starting-out#im-a-list-comprehension">this</a> from LYAHFGG.
</span>, and a list comprehension is just the
Haskell version of a set comprehension or <i>set-builder
notation</i><label for="10" class="margin-toggle sidenote-number"></label><input type="checkbox" id="10" class="margin-toggle"/><span class="sidenote">
See Wikipedia’s <a href="https://en.wikipedia.org/wiki/Set-builder_notation">Set-builder notation</a>
</span> from set theory. And it’s going through the multiples
of \(15\) and \(85\), one after the other like this [writing on the board]
</p>
<pre class="example" id="org2cfb240">
15 30 45 60 75 90 105 120 ... 240 255
85 170 225
</pre>
<p>
<span class="fraktur">ππ―π°π²π©π:</span> [continuing]
making pairs of all these possible combinations until there’s a pair
that match, that share the same multiple, which is \(255\;\). <br />
<span class="fraktur">ππ±π’:</span> So let’s change it
a bit. What happens if you <i>don’t</i> have the filter that selects just
the equal pairs <i>and</i> you don’t take just the first one like you did
with that <code>take 1</code>? <br />
<span class="fraktur">ππ―π°π²π©π:</span> Right, I know
what you mean. Here it is [typing]. Here’s all the pairs of the two
intervals in all possible combinations — this time only the first
\(15\) multiples of \(15\) and \(85\:\) so it doesn’t get too big
</p>
<pre class="example" id="orgc4535ce">
myLCM2 dnom1 dnom2 = [((*dnom1)x,(*dnom2)y) |