Skip to content

Commit 2e563a6

Browse files
committed
Add zine on Haskell functors.
1 parent ea30ff6 commit 2e563a6

File tree

6 files changed

+364
-0
lines changed

6 files changed

+364
-0
lines changed

haskell/functors/assets/crane.png

125 KB
Loading

haskell/functors/index.html

+113
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="utf-8">
5+
<title>Haskell zine: functors</title>
6+
<style>@font-face{font-family:'threemedium';src:url('https://alicja.dev/assets/fonts/three.eot');src:url('https://alicja.dev/assets/fonts/three.eot?#iefix') format('embedded-opentype'),url('https://alicja.dev/assets/fonts/three.woff2') format('woff2'),url('https://alicja.dev/assets/fonts/three.woff') format('woff'),url('https://alicja.dev/assets/fonts/three.ttf') format('truetype'),url('https://alicja.dev/assets/fonts/three.svg#threemedium') format('svg');font-weight:normal;font-style:normal}body{font:18px "Trebuchet MS", Helvetica, sans-serif;font:32px "threemedium";margin-top:20px;text-align:right}input[type="checkbox"], input[type="radio"]{position:absolute;visibility:hidden}#trebuchet + label,#three + label{margin-right:30px;cursor:pointer;color:#000}#trebuchet + label{font:18px "Trebuchet MS", Helvetica, sans-serif}#three + label{font:32px "threemedium"}#three:checked + .three-label{color:#b2b3b8;display:none}#trebuchet:checked + .trebuchet-label{color:#b2b3b8;display:none}#three:checked ~ .zine{font:32px "threemedium"}#trebuchet:checked ~ .zine{font:18px "Trebuchet MS", Helvetica, sans-serif}.zine{margin:0 auto;max-width:840px;text-align:left}@media print{@page{ size:auto portrait; margin:0cm; }.zine{ margin:1cm; -webkit-print-color-adjust:exact; }#trebuchet + label, #three + label{ display:none; }}.zine{padding-bottom:1em}.functor{color:#ee4266}.crane{height:350px;position:absolute;top:50px;float:right}.defintion-line{display:block;margin-left:1em}.explanation,.functor-laws,.functor-example,.functor-class{margin-top:1em}.element,.value{display:inline-block}.function{width:65px;text-align:center}.type{width:120px}.functor-example{font-size:0.9em}.functor-call{margin:10px 0}.def,.apply,.output{display:block}.output{color:#45454e}.comment{color:#b2b3b8;font-size:0.9em}.input-function{color:#8f4898}</style>
7+
</head>
8+
<body>
9+
<input id="trebuchet" type="radio" name="font">
10+
<label for="trebuchet" class="font-button trebuchet-label">Trebuchet</label>
11+
12+
<input id="three" type="radio" name="font" checked>
13+
<label for="three" class="font-button three-label">Three</label>
14+
15+
<div class="zine">
16+
<h1>Functors and lifting</h1>
17+
18+
<span class="annotation">Functors are like cranes lifting a function into a context</span>
19+
20+
<img src="./assets/crane.png" class="crane">
21+
22+
<div class="functor-class">
23+
class Functor <span class="functor">f</span> where
24+
<span class="defintion-line">
25+
<span class="functor">fmap</span> :: (a -> b) -> <span class="functor">f</span> a -> <span class="functor">f</span> b
26+
</span>
27+
</span>
28+
29+
<div class="explanation">
30+
It's like function application in the context of <span class="functor">f</span>:
31+
<div class="type-defintion">
32+
<div class="element">
33+
<span class="value function">($)</span>
34+
</div>
35+
<div class="element operator">
36+
<span class="value type operator">::</span>
37+
</div>
38+
<div class="element">
39+
<span class="value">(a -> b)</span>
40+
</div>
41+
<div class="element">
42+
<span class="value operator">-></span>
43+
</div>
44+
<div class="element">
45+
<span class="value">&nbsp;&nbsp;a</span>
46+
</div>
47+
<div class="element">
48+
<span class="value operator">-></span>
49+
</div>
50+
<div class="element">
51+
<span class="annotation"></span>
52+
<span class="value">&nbsp;&nbsp;b</span>
53+
</div>
54+
</div>
55+
<div class="type-definition">
56+
<div class="element">
57+
<span class="value function functor">(<$>)</span>
58+
</div>
59+
<div class="element operator">
60+
<span class="value type operator">:: Functor <span class="functor">f</span> =></span>
61+
</div>
62+
<div class="element">
63+
<span class="value">(a -> b)</span>
64+
</div>
65+
<div class="element">
66+
<span class="value operator">-></span>
67+
</div>
68+
<div class="element">
69+
<span class="value"><span class="functor">f</span>&nbsp;a</span>
70+
</div>
71+
<div class="element">
72+
<span class="value operator">-></span>
73+
</div>
74+
<div class="element">
75+
<span class="annotation"></span>
76+
<span class="value"><span class="functor">f</span>&nbsp;b</span>
77+
</div>
78+
</div>
79+
</span>
80+
81+
<div class="functor-example">
82+
<strong>Let's work through an example</strong>
83+
<span class="def">let <span class="input-function">replace</span> = const "a" <span class="comment"><- function to apply</span></span>
84+
<span class="def">let value = [ Just [ "this", "that" ] ] <span class="comment"><- variable to change</span></span>
85+
86+
<div class="functor-call">
87+
<span class="apply"><span class="input-function">replace</span> value <span class="comment"><- apply to []</span></span>
88+
<span class="output">"a"</span>
89+
</div>
90+
91+
<div class="functor-call">
92+
<span class="apply"><span class="functor">fmap</span> <span class="input-function">replace</span> value <span class="comment"><- lift once - apply to Just</span></span>
93+
<span class="output">[ "a" ]</span>
94+
</div>
95+
96+
<div class="functor-call">
97+
<span class="apply">(<span class="functor">fmap</span> . <span class="functor">fmap</span>) <span class="input-function">replace</span> value <span class="comment"><- lift twice - apply to the internal list</span></span>
98+
<span class="output">[ Just "a" ]</span>
99+
</div>
100+
101+
<div class="functor-call">
102+
<span class="apply">(<span class="functor">fmap</span> . <span class="functor">fmap</span> . <span class="functor">fmap</span>) <span class="input-function">replace</span> value <span class="comment"><- lift thrice - apply to the elements of the internal list</span></span>
103+
<span class="output">[ Just [ "a", "a" ] ]</span>
104+
</div>
105+
106+
<div class="functor-call">
107+
<span class="apply">(<span class="functor">fmap</span> . <span class="functor">fmap</span> . <span class="functor">fmap</span> . <span class="functor">fmap</span>) <span class="input-function">replace</span> value <span class="comment"><- lift one last time - apply to each letter of each string</span></span>
108+
<span class="output">[ Just [ [ "a", "a", "a", "a" ], [ "a", "a", "a", "a" ] ] ]</span>
109+
</div>
110+
</div>
111+
</div>
112+
</body>
113+
</html>
+95
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
<h1>Functors and lifting</h1>
2+
3+
<span class="annotation">Functors are like cranes lifting a function into a context</span>
4+
5+
<img src="./assets/crane.png" class="crane">
6+
7+
<div class="functor-class">
8+
class Functor <span class="functor">f</span> where
9+
<span class="defintion-line">
10+
<span class="functor">fmap</span> :: (a -> b) -> <span class="functor">f</span> a -> <span class="functor">f</span> b
11+
</span>
12+
</span>
13+
14+
<div class="explanation">
15+
It's like function application in the context of <span class="functor">f</span>:
16+
<div class="type-defintion">
17+
<div class="element">
18+
<span class="value function">($)</span>
19+
</div>
20+
<div class="element operator">
21+
<span class="value type operator">::</span>
22+
</div>
23+
<div class="element">
24+
<span class="value">(a -> b)</span>
25+
</div>
26+
<div class="element">
27+
<span class="value operator">-></span>
28+
</div>
29+
<div class="element">
30+
<span class="value">&nbsp;&nbsp;a</span>
31+
</div>
32+
<div class="element">
33+
<span class="value operator">-></span>
34+
</div>
35+
<div class="element">
36+
<span class="annotation"></span>
37+
<span class="value">&nbsp;&nbsp;b</span>
38+
</div>
39+
</div>
40+
<div class="type-definition">
41+
<div class="element">
42+
<span class="value function functor">(<$>)</span>
43+
</div>
44+
<div class="element operator">
45+
<span class="value type operator">:: Functor <span class="functor">f</span> =></span>
46+
</div>
47+
<div class="element">
48+
<span class="value">(a -> b)</span>
49+
</div>
50+
<div class="element">
51+
<span class="value operator">-></span>
52+
</div>
53+
<div class="element">
54+
<span class="value"><span class="functor">f</span>&nbsp;a</span>
55+
</div>
56+
<div class="element">
57+
<span class="value operator">-></span>
58+
</div>
59+
<div class="element">
60+
<span class="annotation"></span>
61+
<span class="value"><span class="functor">f</span>&nbsp;b</span>
62+
</div>
63+
</div>
64+
</span>
65+
66+
<div class="functor-example">
67+
<strong>Let's work through an example</strong>
68+
<span class="def">let <span class="input-function">replace</span> = const "a" <span class="comment"><- function to apply</span></span>
69+
<span class="def">let value = [ Just [ "this", "that" ] ] <span class="comment"><- variable to change</span></span>
70+
71+
<div class="functor-call">
72+
<span class="apply"><span class="input-function">replace</span> value <span class="comment"><- apply to []</span></span>
73+
<span class="output">"a"</span>
74+
</div>
75+
76+
<div class="functor-call">
77+
<span class="apply"><span class="functor">fmap</span> <span class="input-function">replace</span> value <span class="comment"><- lift once - apply to Just</span></span>
78+
<span class="output">[ "a" ]</span>
79+
</div>
80+
81+
<div class="functor-call">
82+
<span class="apply">(<span class="functor">fmap</span> . <span class="functor">fmap</span>) <span class="input-function">replace</span> value <span class="comment"><- lift twice - apply to the internal list</span></span>
83+
<span class="output">[ Just "a" ]</span>
84+
</div>
85+
86+
<div class="functor-call">
87+
<span class="apply">(<span class="functor">fmap</span> . <span class="functor">fmap</span> . <span class="functor">fmap</span>) <span class="input-function">replace</span> value <span class="comment"><- lift thrice - apply to the elements of the internal list</span></span>
88+
<span class="output">[ Just [ "a", "a" ] ]</span>
89+
</div>
90+
91+
<div class="functor-call">
92+
<span class="apply">(<span class="functor">fmap</span> . <span class="functor">fmap</span> . <span class="functor">fmap</span> . <span class="functor">fmap</span>) <span class="input-function">replace</span> value <span class="comment"><- lift one last time - apply to each letter of each string</span></span>
93+
<span class="output">[ Just [ [ "a", "a", "a", "a" ], [ "a", "a", "a", "a" ] ] ]</span>
94+
</div>
95+
</div>

haskell/functors/partials/index.html

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="utf-8">
5+
<title>Haskell zine: functors</title>
6+
<style></style>
7+
</head>
8+
<body>
9+
<input id="trebuchet" type="radio" name="font">
10+
<label for="trebuchet" class="font-button trebuchet-label">Trebuchet</label>
11+
12+
<input id="three" type="radio" name="font" checked>
13+
<label for="three" class="font-button three-label">Three</label>
14+
15+
<div class="zine">
16+
{{ functors }}
17+
</div>
18+
</body>
19+
</html>

haskell/functors/styles/functors.scss

+67
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
.zine {
2+
padding-bottom: 1em;
3+
}
4+
5+
.functor {
6+
color: $pink0;
7+
}
8+
9+
.crane {
10+
height: 350px;
11+
position: absolute;
12+
top: 50px;
13+
float: right;
14+
}
15+
16+
.defintion-line {
17+
display: block;
18+
margin-left: 1em;
19+
}
20+
21+
.explanation,
22+
.functor-laws,
23+
.functor-example,
24+
.functor-class {
25+
margin-top: 1em;
26+
}
27+
28+
.element,
29+
.value {
30+
display: inline-block;
31+
}
32+
33+
.function {
34+
width: 65px;
35+
text-align: center;
36+
}
37+
38+
.type {
39+
width: 120px;
40+
}
41+
42+
.functor-example {
43+
font-size: 0.9em;
44+
}
45+
46+
.functor-call {
47+
margin: 10px 0;
48+
}
49+
50+
.def,
51+
.apply,
52+
.output {
53+
display: block;
54+
}
55+
56+
.output {
57+
color: $grey0;
58+
}
59+
60+
.comment {
61+
color: $grey1;
62+
font-size: 0.9em;
63+
}
64+
65+
.input-function {
66+
color: $purple0;
67+
}

haskell/functors/styles/main.scss

+70
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
@font-face {
2+
font-family: 'threemedium';
3+
src: url('https://alicja.dev/assets/fonts/three.eot');
4+
src: url('https://alicja.dev/assets/fonts/three.eot?#iefix') format('embedded-opentype'),
5+
url('https://alicja.dev/assets/fonts/three.woff2') format('woff2'),
6+
url('https://alicja.dev/assets/fonts/three.woff') format('woff'),
7+
url('https://alicja.dev/assets/fonts/three.ttf') format('truetype'),
8+
url('https://alicja.dev/assets/fonts/three.svg#threemedium') format('svg');
9+
font-weight: normal;
10+
font-style: normal;
11+
}
12+
13+
body {
14+
font: 18px "Trebuchet MS", Helvetica, sans-serif;
15+
font: 32px "threemedium";
16+
margin-top: 20px;
17+
text-align: right;
18+
}
19+
20+
input[type="checkbox"], input[type="radio"] {
21+
position: absolute;
22+
visibility: hidden;
23+
}
24+
25+
#trebuchet + label,
26+
#three + label {
27+
margin-right: 30px;
28+
cursor: pointer;
29+
color: #000;
30+
}
31+
32+
#trebuchet + label {
33+
font: 18px "Trebuchet MS", Helvetica, sans-serif;
34+
}
35+
36+
#three + label {
37+
font: 32px "threemedium";
38+
}
39+
40+
#three:checked + .three-label {
41+
color: $grey1;
42+
display: none;
43+
}
44+
45+
#trebuchet:checked + .trebuchet-label {
46+
color:$grey1;
47+
display: none;
48+
}
49+
50+
#three:checked ~ .zine {
51+
font: 32px "threemedium";
52+
}
53+
54+
#trebuchet:checked ~ .zine {
55+
font: 18px "Trebuchet MS", Helvetica, sans-serif;
56+
}
57+
58+
.zine {
59+
margin: 0 auto;
60+
max-width: 840px;
61+
text-align: left;
62+
}
63+
64+
@media print {
65+
@page { size: auto portrait; margin: 0cm; }
66+
.zine { margin: 1cm; -webkit-print-color-adjust: exact; }
67+
#trebuchet + label, #three + label { display: none; }
68+
}
69+
70+
@include functors;

0 commit comments

Comments
 (0)