git.iko.soy/ikoHSE/sc-lectures
on dependabot/npm_and_yarn/reveal.js/engine.io-3.6.1 help sign in
714 lines 86 kB history raw
1<!DOCTYPE html>
2<html>
3<head>
4 <meta charset="utf-8">
5 <meta name="generator" content="pandoc">
6 <meta name="author" content="Ilya Kostyuchenko">
7 <title>2</title>
8 <meta name="apple-mobile-web-app-capable" content="yes">
9 <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
10 <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, minimal-ui">
11 <link rel="stylesheet" href="reveal.js/css/reset.css">
12 <link rel="stylesheet" href="reveal.js/css/reveal.css">
13 <style>
14 code{white-space: pre-wrap;}
15 span.smallcaps{font-variant: small-caps;}
16 span.underline{text-decoration: underline;}
17 div.column{display: inline-block; vertical-align: top; width: 50%;}
18 div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;}
19 ul.task-list{list-style: none;}
20 pre > code.sourceCode { white-space: pre; position: relative; }
21 pre > code.sourceCode > span { display: inline-block; line-height: 1.25; }
22 pre > code.sourceCode > span:empty { height: 1.2em; }
23 code.sourceCode > span { color: inherit; text-decoration: inherit; }
24 div.sourceCode { margin: 1em 0; }
25 pre.sourceCode { margin: 0; }
26 @media screen {
27 div.sourceCode { overflow: auto; }
28 }
29 @media print {
30 pre > code.sourceCode { white-space: pre-wrap; }
31 pre > code.sourceCode > span { text-indent: -5em; padding-left: 5em; }
32 }
33 pre.numberSource code
34 { counter-reset: source-line 0; }
35 pre.numberSource code > span
36 { position: relative; left: -4em; counter-increment: source-line; }
37 pre.numberSource code > span > a:first-child::before
38 { content: counter(source-line);
39 position: relative; left: -1em; text-align: right; vertical-align: baseline;
40 border: none; display: inline-block;
41 -webkit-touch-callout: none; -webkit-user-select: none;
42 -khtml-user-select: none; -moz-user-select: none;
43 -ms-user-select: none; user-select: none;
44 padding: 0 4px; width: 4em;
45 background-color: #232629;
46 color: #7a7c7d;
47 }
48 pre.numberSource { margin-left: 3em; border-left: 1px solid #7a7c7d; padding-left: 4px; }
49 div.sourceCode
50 { color: #ffffff; background-color: #000000; }
51 @media screen {
52 pre > code.sourceCode > span > a:first-child::before { text-decoration: underline; }
53 }
54 code span. { color: #ffffff; } /* Normal */
55 code span.al { color: #95da4c; background-color: #4d1f24; font-weight: bold; } /* Alert */
56 code span.an { color: #86d5a4; } /* Annotation */
57 code span.at { color: #94cbf0; } /* Attribute */
58 code span.bn { color: #ffb06a; } /* BaseN */
59 code span.bu { color: #bdd1d3; } /* BuiltIn */
60 code span.cf { color: #ffd998; font-weight: bold; } /* ControlFlow */
61 code span.ch { color: #a4e0ff; } /* Char */
62 code span.cn { color: #73d9d9; font-weight: bold; } /* Constant */
63 code span.co { color: #a1a6a8; } /* Comment */
64 code span.cv { color: #b6c8c9; } /* CommentVar */
65 code span.do { color: #a43340; } /* Documentation */
66 code span.dt { color: #7cc0ec; } /* DataType */
67 code span.dv { color: #f6b77f; } /* DecVal */
68 code span.er { color: #e9848e; text-decoration: underline; } /* Error */
69 code span.ex { color: #96d5ff; font-weight: bold; } /* Extension */
70 code span.fl { color: #fdae67; } /* Float */
71 code span.fu { color: #d487f4; } /* Function */
72 code span.im { color: #76e8a6; } /* Import */
73 code span.in { color: #f6b176; } /* Information */
74 code span.kw { color: #ebebc9; font-weight: bold; } /* Keyword */
75 code span.op { color: #ececde; } /* Operator */
76 code span.ot { color: #86e9b0; } /* Other */
77 code span.pp { color: #62e298; } /* Preprocessor */
78 code span.re { color: #83c7f4; background-color: #153042; } /* RegionMarker */
79 code span.sc { color: #80ccf4; } /* SpecialChar */
80 code span.ss { color: #ff909b; } /* SpecialString */
81 code span.st { color: #ff9f9f; } /* String */
82 code span.va { color: #56d4d4; } /* Variable */
83 code span.vs { color: #eca2a9; } /* VerbatimString */
84 code span.wa { color: #eca2a9; } /* Warning */
85 </style>
86 <link rel="stylesheet" href="reveal.js/css/theme/superblack.css" id="theme">
87 <!-- Printing and PDF exports -->
88 <script>
89 var link = document.createElement( 'link' );
90 link.rel = 'stylesheet';
91 link.type = 'text/css';
92 link.href = window.location.search.match( /print-pdf/gi ) ? 'reveal.js/css/print/pdf.css' : 'reveal.js/css/print/paper.css';
93 document.getElementsByTagName( 'head' )[0].appendChild( link );
94 </script>
95 <!--[if lt IE 9]>
96 <script src="reveal.js/lib/js/html5shiv.js"></script>
97 <![endif]-->
98 <style>
99 div.sourceCode {
100 background-color: transparent;
101 overflow: auto;
102 margin: 0em;
103 }
105 pre.sourceCode {
106 margin: 8px auto;
107 }
108 </style>
109</head>
110<body>
111 <div class="reveal">
112 <div class="slides">
115<section id="функциональное-программирование" class="slide level1">
116<h1>Функциональное программирование</h1>
117</section>
118<section id="структуры" class="slide level1">
119<h1>Структуры</h1>
120<div class="sourceCode" id="cb1"><pre class="sourceCode haskell fragment"><code class="sourceCode haskell"><span id="cb1-1"><a href="#cb1-1"></a><span class="kw">data</span> <span class="dt">CircleType</span> <span class="ot">=</span> <span class="dt">Circle</span> <span class="dt">Double</span> <span class="dt">Double</span> <span class="dt">Double</span></span>
121<span id="cb1-2"><a href="#cb1-2"></a><span class="kw">data</span> <span class="dt">RectangleType</span> <span class="ot">=</span> <span class="dt">Rectangle</span> <span class="dt">Double</span> <span class="dt">Double</span> <span class="dt">Double</span> <span class="dt">Double</span></span>
122<span id="cb1-3"><a href="#cb1-3"></a></span>
123<span id="cb1-4"><a href="#cb1-4"></a><span class="kw">data</span> <span class="dt">Shape</span> <span class="ot">=</span></span>
124<span id="cb1-5"><a href="#cb1-5"></a> <span class="dt">CircleShape</span> <span class="dt">CircleType</span> <span class="op">|</span> <span class="dt">RectangleShape</span> <span class="dt">RectangleType</span></span></code></pre></div>
125<div class="sourceCode" id="cb2"><pre class="sourceCode haskell fragment"><code class="sourceCode haskell"><span id="cb2-1"><a href="#cb2-1"></a>shape <span class="ot">=</span> <span class="dt">CircleShape</span> (<span class="dt">Circle</span> <span class="dv">0</span> <span class="dv">0</span> <span class="dv">2</span>)</span>
126<span id="cb2-2"><a href="#cb2-2"></a>otherShape <span class="ot">=</span> <span class="dt">RectangleShape</span> (<span class="dt">Rectangle</span> <span class="dv">1</span> <span class="dv">2</span> <span class="dv">3</span> <span class="dv">4</span>)</span></code></pre></div>
127</section>
128<section class="slide level1">
130<h2 id="структура-человек">Структура “человек”</h2>
131<p>Имя, Фамилия, Отчество, Адрес, Почта, Возраст</p>
132<div class="sourceCode" id="cb3"><pre class="sourceCode haskell fragment"><code class="sourceCode haskell"><span id="cb3-1"><a href="#cb3-1"></a><span class="kw">data</span> <span class="dt">Person</span> <span class="ot">=</span></span>
133<span id="cb3-2"><a href="#cb3-2"></a> <span class="dt">Person</span> <span class="dt">String</span> <span class="dt">String</span> <span class="dt">String</span> <span class="dt">String</span> <span class="dt">String</span> <span class="dt">Natural</span></span></code></pre></div>
134<p><img data-src="images/ohno.png" class="fragment" height="200" /></p>
135</section>
136<section class="slide level1">
138<h2 id="функции">Функции!</h2>
139<div class="sourceCode" id="cb4"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb4-1"><a href="#cb4-1"></a><span class="kw">data</span> <span class="dt">Person</span> <span class="ot">=</span></span>
140<span id="cb4-2"><a href="#cb4-2"></a> <span class="dt">Person</span> <span class="dt">String</span> <span class="dt">String</span> <span class="dt">String</span> <span class="dt">String</span> <span class="dt">String</span> <span class="dt">Natural</span></span></code></pre></div>
141<div class="sourceCode" id="cb5"><pre class="sourceCode haskell fragment"><code class="sourceCode haskell"><span id="cb5-1"><a href="#cb5-1"></a><span class="ot">firstName ::</span> <span class="dt">Person</span> <span class="ot">-&gt;</span> <span class="dt">String</span></span>
142<span id="cb5-2"><a href="#cb5-2"></a>firstName (<span class="dt">Person</span> name _ _ _ _ _) <span class="ot">=</span> name</span></code></pre></div>
143<div class="sourceCode" id="cb6"><pre class="sourceCode haskell fragment"><code class="sourceCode haskell"><span id="cb6-1"><a href="#cb6-1"></a><span class="ot">setFirstName ::</span> <span class="dt">String</span> <span class="ot">-&gt;</span> <span class="dt">Person</span> <span class="ot">-&gt;</span> <span class="dt">Person</span></span>
144<span id="cb6-2"><a href="#cb6-2"></a>setFirstName</span>
145<span id="cb6-3"><a href="#cb6-3"></a> newName</span>
146<span id="cb6-4"><a href="#cb6-4"></a> (<span class="dt">Person</span> _ lName mName address email age)</span>
147<span id="cb6-5"><a href="#cb6-5"></a> <span class="ot">=</span> <span class="dt">Person</span> newName lName mName address email age</span></code></pre></div>
148<div class="sourceCode" id="cb7"><pre class="sourceCode haskell fragment"><code class="sourceCode haskell"><span id="cb7-1"><a href="#cb7-1"></a><span class="ot">lastName ::</span> <span class="dt">Person</span> <span class="ot">-&gt;</span> <span class="dt">String</span></span>
149<span id="cb7-2"><a href="#cb7-2"></a>lastName (<span class="dt">Person</span> _ lName _ _ _ _) <span class="ot">=</span> lName</span>
150<span id="cb7-3"><a href="#cb7-3"></a><span class="ot">setLastName ::</span> <span class="dt">String</span> <span class="ot">-&gt;</span> <span class="dt">Person</span> <span class="ot">-&gt;</span> <span class="dt">Person</span></span>
151<span id="cb7-4"><a href="#cb7-4"></a>setLastName</span>
152<span id="cb7-5"><a href="#cb7-5"></a> newLastName</span>
153<span id="cb7-6"><a href="#cb7-6"></a> (<span class="dt">Person</span> fName _ mName address email age)</span>
154<span id="cb7-7"><a href="#cb7-7"></a> <span class="ot">=</span> <span class="dt">Person</span> fName newLastName mName address email age</span></code></pre></div>
155</section>
156<section class="slide level1">
158<div class="sourceCode" id="cb8"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb8-1"><a href="#cb8-1"></a><span class="ot">middleName ::</span> <span class="dt">Person</span> <span class="ot">-&gt;</span> <span class="dt">String</span></span>
159<span id="cb8-2"><a href="#cb8-2"></a>middleName (<span class="dt">Person</span> _ _ mName _ _ _) <span class="ot">=</span> mName</span>
160<span id="cb8-3"><a href="#cb8-3"></a><span class="ot">setMiddleName ::</span> <span class="dt">String</span> <span class="ot">-&gt;</span> <span class="dt">Person</span> <span class="ot">-&gt;</span> <span class="dt">Person</span></span>
161<span id="cb8-4"><a href="#cb8-4"></a>setMiddleName</span>
162<span id="cb8-5"><a href="#cb8-5"></a> newMiddleName</span>
163<span id="cb8-6"><a href="#cb8-6"></a> (<span class="dt">Person</span> fName lName _ address email age)</span>
164<span id="cb8-7"><a href="#cb8-7"></a> <span class="ot">=</span> <span class="dt">Person</span> fName lName newMiddleName address email age</span></code></pre></div>
165<p><img data-src="images/ohno.png" class="fragment" height="200" /></p>
166<p><span class="fragment">А что если структуры еще больше?</span></p>
167</section>
168<section class="slide level1">
170<h2 id="record-syntax">Record syntax</h2>
171<div class="sourceCode" id="cb9"><pre class="sourceCode haskell fragment"><code class="sourceCode haskell"><span id="cb9-1"><a href="#cb9-1"></a><span class="kw">data</span> <span class="dt">Person</span></span>
172<span id="cb9-2"><a href="#cb9-2"></a> <span class="ot">=</span> <span class="dt">Person</span></span>
173<span id="cb9-3"><a href="#cb9-3"></a> {<span class="ot"> firstName ::</span> <span class="dt">String</span>,</span>
174<span id="cb9-4"><a href="#cb9-4"></a><span class="ot"> lastName ::</span> <span class="dt">String</span>,</span>
175<span id="cb9-5"><a href="#cb9-5"></a><span class="ot"> middleName ::</span> <span class="dt">String</span>,</span>
176<span id="cb9-6"><a href="#cb9-6"></a><span class="ot"> address ::</span> <span class="dt">String</span>,</span>
177<span id="cb9-7"><a href="#cb9-7"></a><span class="ot"> email ::</span> <span class="dt">String</span>,</span>
178<span id="cb9-8"><a href="#cb9-8"></a><span class="ot"> age ::</span> <span class="dt">Natural</span></span>
179<span id="cb9-9"><a href="#cb9-9"></a> }</span></code></pre></div>
180<div class="sourceCode" id="cb10"><pre class="sourceCode haskell fragment"><code class="sourceCode haskell"><span id="cb10-1"><a href="#cb10-1"></a><span class="co">-- Автоматически генерируются компилятором!</span></span>
181<span id="cb10-2"><a href="#cb10-2"></a><span class="ot">firstName ::</span> <span class="dt">Person</span> <span class="ot">-&gt;</span> <span class="dt">String</span></span>
182<span id="cb10-3"><a href="#cb10-3"></a><span class="ot">lastName ::</span> <span class="dt">Person</span> <span class="ot">-&gt;</span> <span class="dt">String</span></span>
183<span id="cb10-4"><a href="#cb10-4"></a><span class="co">-- ...</span></span></code></pre></div>
184<div class="sourceCode" id="cb11"><pre class="sourceCode haskell fragment"><code class="sourceCode haskell"><span id="cb11-1"><a href="#cb11-1"></a><span class="ot">setFirstName ::</span> <span class="dt">String</span> <span class="ot">-&gt;</span> <span class="dt">Person</span> <span class="ot">-&gt;</span> <span class="dt">String</span></span>
185<span id="cb11-2"><a href="#cb11-2"></a>setFirstName newName person <span class="ot">=</span> person {firstName <span class="ot">=</span> newName}</span>
186<span id="cb11-3"><a href="#cb11-3"></a><span class="co">-- Делает копию, заменяя одно (или нескеолько) поле.</span></span>
187<span id="cb11-4"><a href="#cb11-4"></a><span class="co">-- (То есть функции set... не нужны)</span></span></code></pre></div>
188</section>
189<section id="абстракция" class="slide level1">
190<h1>Абстракция</h1>
191</section>
192<section class="slide level1">
194<blockquote>
195<p>Полиморфизм – одну реализацию можно применять к разным типам.</p>
196</blockquote>
197</section>
198<section class="slide level1">
200<div class="sourceCode" id="cb12"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb12-1"><a href="#cb12-1"></a><span class="fu">length</span><span class="ot"> ::</span> [a] <span class="ot">-&gt;</span> <span class="dt">Int</span></span></code></pre></div>
201<div class="sourceCode" id="cb13"><pre class="sourceCode haskell fragment"><code class="sourceCode haskell"><span id="cb13-1"><a href="#cb13-1"></a><span class="fu">map</span><span class="ot"> ::</span> (a <span class="ot">-&gt;</span> b) <span class="ot">-&gt;</span> [a] <span class="ot">-&gt;</span> [b]</span></code></pre></div>
202<div class="sourceCode" id="cb14"><pre class="sourceCode haskell fragment"><code class="sourceCode haskell"><span id="cb14-1"><a href="#cb14-1"></a><span class="fu">filter</span><span class="ot"> ::</span> (a <span class="ot">-&gt;</span> <span class="dt">Bool</span>) <span class="ot">-&gt;</span> [a] <span class="ot">-&gt;</span> [a]</span></code></pre></div>
203<p><span class="fragment">Problem: сама функция с <code>a</code> и <code>b</code> делать ничего не может – она про них ничего не знает.</span></p>
204</section>
205<section class="slide level1">
207<div class="sourceCode" id="cb15"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb15-1"><a href="#cb15-1"></a><span class="ot">quicksort ::</span> [<span class="dt">Int</span>] <span class="ot">-&gt;</span> [<span class="dt">Int</span>]</span></code></pre></div>
208<div class="sourceCode" id="cb16"><pre class="sourceCode haskell fragment"><code class="sourceCode haskell"><span id="cb16-1"><a href="#cb16-1"></a><span class="ot">quicksort ::</span> [a] <span class="ot">-&gt;</span> [a]</span></code></pre></div>
209<p><span class="fragment">Откуда <code>sort</code> узнает что такое <code>a</code> и как их сравнивать?</span></p>
210</section>
211<section class="slide level1">
213<h2 id="typeclass">Typeclass</h2>
214</section>
215<section class="slide level1">
217<p>Самое близкое – интрефейс.</p>
218<blockquote>
219<p>Описывает свойства, которыми должен обладать объект</p>
220</blockquote>
221</section>
222<section class="slide level1">
224<div class="sourceCode" id="cb17"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb17-1"><a href="#cb17-1"></a><span class="kw">class</span> <span class="dt">Eq</span> a <span class="kw">where</span></span>
225<span id="cb17-2"><a href="#cb17-2"></a><span class="ot"> (==) ::</span> a <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> <span class="dt">Bool</span></span></code></pre></div>
226<p><span class="fragment"><code>a</code> относится к классу <code>Eq</code> если существует такая функция <code>(==) :: a -&gt; a -&gt; Bool</code></span></p>
227</section>
228<section class="slide level1">
230<div class="sourceCode" id="cb18"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb18-1"><a href="#cb18-1"></a><span class="kw">class</span> <span class="dt">Eq</span> a <span class="kw">where</span></span>
231<span id="cb18-2"><a href="#cb18-2"></a><span class="ot"> (==) ::</span> a <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> <span class="dt">Bool</span></span></code></pre></div>
232<div class="sourceCode" id="cb19"><pre class="sourceCode fragment haskell"><code class="sourceCode haskell"><span id="cb19-1"><a href="#cb19-1"></a><span class="kw">data</span> <span class="dt">PersonType</span> <span class="ot">=</span> <span class="dt">Person</span> <span class="dt">String</span> <span class="dt">Int</span></span></code></pre></div>
233<div class="sourceCode" id="cb20"><pre class="sourceCode fragment haskell"><code class="sourceCode haskell"><span id="cb20-1"><a href="#cb20-1"></a><span class="kw">instance</span> <span class="dt">Eq</span> <span class="dt">PersonType</span> <span class="kw">where</span></span>
234<span id="cb20-2"><a href="#cb20-2"></a> (<span class="dt">Person</span> name1 age1) <span class="op">==</span> (<span class="dt">Person</span> name2 age2) <span class="ot">=</span></span>
235<span id="cb20-3"><a href="#cb20-3"></a> name1 <span class="op">==</span> name2 <span class="op">&amp;&amp;</span> age1 <span class="op">==</span> age2</span></code></pre></div>
236<p><span class="fragment">instance – “удовлетворяет”, а не “экземпляр”.</span></p>
237</section>
238<section class="slide level1">
240<h2 id="использование">Использование</h2>
241<div class="sourceCode" id="cb21"><pre class="sourceCode haskell fragment"><code class="sourceCode haskell"><span id="cb21-1"><a href="#cb21-1"></a><span class="ot">notEqual ::</span> a <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> <span class="dt">Bool</span></span></code></pre></div>
242<div class="sourceCode" id="cb22"><pre class="sourceCode haskell fragment"><code class="sourceCode haskell"><span id="cb22-1"><a href="#cb22-1"></a><span class="ot">notEqual ::</span> <span class="dt">Eq</span> a <span class="ot">=&gt;</span> a <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> <span class="dt">Bool</span></span>
243<span id="cb22-2"><a href="#cb22-2"></a>notEqual a b <span class="ot">=</span> <span class="fu">not</span> (a <span class="op">==</span> b)</span></code></pre></div>
244</section>
245<section class="slide level1">
247<div class="sourceCode" id="cb23"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb23-1"><a href="#cb23-1"></a><span class="kw">class</span> <span class="dt">Eq</span> a <span class="ot">=&gt;</span> <span class="dt">Ord</span> a <span class="kw">where</span></span>
248<span id="cb23-2"><a href="#cb23-2"></a><span class="ot"> (&lt;=) ::</span> a <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> <span class="dt">Bool</span></span></code></pre></div>
249<p><span class="fragment"><code>a</code> относится к классу <code>Ord</code> если он относится к классу <code>Ord</code> и существует такая функция <code>(&lt;=) :: a -&gt; a -&gt; Bool</code></span></p>
250</section>
251<section class="slide level1">
253<div class="sourceCode" id="cb24"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb24-1"><a href="#cb24-1"></a><span class="kw">class</span> <span class="dt">Eq</span> a <span class="ot">=&gt;</span> <span class="dt">Ord</span> a <span class="kw">where</span></span>
254<span id="cb24-2"><a href="#cb24-2"></a><span class="ot"> (&lt;=) ::</span> a <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> <span class="dt">Bool</span></span></code></pre></div>
255<div class="sourceCode" id="cb25"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb25-1"><a href="#cb25-1"></a><span class="kw">data</span> <span class="dt">PersonType</span> <span class="ot">=</span> <span class="dt">Person</span> <span class="dt">String</span> <span class="dt">Int</span></span></code></pre></div>
256<div class="sourceCode" id="cb26"><pre class="sourceCode fragment haskell"><code class="sourceCode haskell"><span id="cb26-1"><a href="#cb26-1"></a><span class="kw">instance</span> <span class="dt">Eq</span> <span class="dt">PersonType</span> <span class="kw">where</span></span>
257<span id="cb26-2"><a href="#cb26-2"></a> (<span class="dt">Person</span> name1 age1) <span class="op">==</span> (<span class="dt">Person</span> name2 age2) <span class="ot">=</span></span>
258<span id="cb26-3"><a href="#cb26-3"></a> name1 <span class="op">==</span> name2 <span class="op">&amp;&amp;</span> age1 <span class="op">==</span> age2</span></code></pre></div>
259<div class="sourceCode" id="cb27"><pre class="sourceCode fragment haskell"><code class="sourceCode haskell"><span id="cb27-1"><a href="#cb27-1"></a><span class="kw">instance</span> <span class="dt">Ord</span> <span class="dt">PersonType</span> <span class="kw">where</span></span>
260<span id="cb27-2"><a href="#cb27-2"></a> (<span class="dt">Person</span> name1 age1) <span class="op">&lt;=</span> (<span class="dt">Person</span> name2 age2) <span class="ot">=</span></span>
261<span id="cb27-3"><a href="#cb27-3"></a> name1 <span class="op">&lt;=</span> name2 <span class="op">&amp;&amp;</span> age1 <span class="op">&lt;=</span> age2</span></code></pre></div>
262</section>
263<section class="slide level1">
265<h2 id="использование-1">Использование</h2>
266<div class="sourceCode" id="cb28"><pre class="sourceCode haskell fragment"><code class="sourceCode haskell"><span id="cb28-1"><a href="#cb28-1"></a><span class="ot">(&gt;) ::</span> <span class="dt">Ord</span> a <span class="ot">=&gt;</span> a <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> <span class="dt">Bool</span></span>
267<span id="cb28-2"><a href="#cb28-2"></a>a <span class="op">&gt;</span> b <span class="ot">=</span> <span class="fu">not</span> (a <span class="op">&lt;=</span> b)</span></code></pre></div>
268<div class="sourceCode" id="cb29"><pre class="sourceCode haskell fragment"><code class="sourceCode haskell"><span id="cb29-1"><a href="#cb29-1"></a><span class="ot">(&gt;=) ::</span> <span class="dt">Ord</span> a <span class="ot">=&gt;</span> a <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> <span class="dt">Bool</span></span>
269<span id="cb29-2"><a href="#cb29-2"></a>a <span class="op">&gt;=</span> b <span class="ot">=</span> a <span class="op">&gt;</span> b <span class="op">||</span> a <span class="op">==</span> b</span></code></pre></div>
270<p><span class="fragment">Тут мы можем использовать <code>&gt;</code> на типах <code>a</code> потому что внутри функции уже есть определение <code>Ord a</code>.</span></p>
271</section>
272<section class="slide level1">
274<p><code>notEqual</code> в стандартной библиотеке определен как <code>/=</code>.</p>
275</section>
276<section class="slide level1">
278<div class="sourceCode" id="cb30"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb30-1"><a href="#cb30-1"></a><span class="fu">max</span><span class="ot"> ::</span> <span class="dt">Ord</span> a <span class="ot">=&gt;</span> a <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> a</span>
279<span id="cb30-2"><a href="#cb30-2"></a><span class="fu">max</span> a b <span class="ot">=</span> <span class="kw">if</span> a <span class="op">&gt;</span> b <span class="kw">then</span> a <span class="kw">else</span> b</span></code></pre></div>
280<p><span class="fragment">Из-за сильной системы типов гарантируется что функция вернет один из своих аргументов.</span></p>
281</section>
282<section class="slide level1">
284<h2 id="case">Case</h2>
285<div class="sourceCode" id="cb31"><pre class="sourceCode haskell fragment"><code class="sourceCode haskell"><span id="cb31-1"><a href="#cb31-1"></a><span class="kw">data</span> <span class="dt">Maybe</span> a <span class="ot">=</span> <span class="dt">Just</span> a <span class="op">|</span> <span class="dt">Nothing</span></span></code></pre></div>
286<div class="sourceCode" id="cb32"><pre class="sourceCode haskell fragment"><code class="sourceCode haskell"><span id="cb32-1"><a href="#cb32-1"></a><span class="ot">isJust ::</span> <span class="dt">Maybe</span> a <span class="ot">-&gt;</span> <span class="dt">Bool</span></span></code></pre></div>
287<div class="sourceCode" id="cb33"><pre class="sourceCode haskell fragment"><code class="sourceCode haskell"><span id="cb33-1"><a href="#cb33-1"></a>isJust <span class="dt">Nothing</span> <span class="ot">=</span> <span class="dt">False</span></span>
288<span id="cb33-2"><a href="#cb33-2"></a>isJust (<span class="dt">Just</span> _) <span class="ot">=</span> <span class="dt">True</span></span></code></pre></div>
289<div class="sourceCode" id="cb34"><pre class="sourceCode haskell fragment"><code class="sourceCode haskell"><span id="cb34-1"><a href="#cb34-1"></a>isJust x <span class="ot">=</span> <span class="kw">case</span> x <span class="kw">of</span></span>
290<span id="cb34-2"><a href="#cb34-2"></a> <span class="dt">Nothing</span> <span class="ot">-&gt;</span> <span class="dt">False</span></span>
291<span id="cb34-3"><a href="#cb34-3"></a> <span class="dt">Just</span> _ <span class="ot">-&gt;</span> <span class="dt">True</span></span></code></pre></div>
292<p><span class="fragment">Просто возможность делать pattern matching где угодно, а не только в аргументах функций.</span></p>
293</section>
294<section class="slide level1">
296<div class="sourceCode" id="cb35"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb35-1"><a href="#cb35-1"></a><span class="fu">maximum</span><span class="ot"> ::</span> <span class="dt">Ord</span> a <span class="ot">=&gt;</span> [a] <span class="ot">-&gt;</span> <span class="dt">Maybe</span> a</span></code></pre></div>
297<div class="sourceCode" id="cb36"><pre class="sourceCode haskell fragment"><code class="sourceCode haskell"><span id="cb36-1"><a href="#cb36-1"></a><span class="fu">max</span><span class="ot"> ::</span> <span class="dt">Ord</span> a <span class="ot">=&gt;</span> a <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> a</span></code></pre></div>
298<div class="sourceCode" id="cb37"><pre class="sourceCode haskell fragment"><code class="sourceCode haskell"><span id="cb37-1"><a href="#cb37-1"></a><span class="fu">maximum</span><span class="ot"> ::</span> <span class="dt">Ord</span> a <span class="ot">=&gt;</span> [a] <span class="ot">-&gt;</span> <span class="dt">Maybe</span> a</span>
299<span id="cb37-2"><a href="#cb37-2"></a><span class="fu">maximum</span> [] <span class="ot">=</span> <span class="dt">Nothing</span></span>
300<span id="cb37-3"><a href="#cb37-3"></a><span class="fu">maximum</span> (x <span class="op">:</span> xs) <span class="ot">=</span> <span class="kw">case</span> <span class="fu">maximum</span> xs <span class="kw">of</span></span>
301<span id="cb37-4"><a href="#cb37-4"></a> <span class="dt">Nothing</span> <span class="ot">-&gt;</span> <span class="dt">Just</span> x</span>
302<span id="cb37-5"><a href="#cb37-5"></a> <span class="dt">Just</span> y <span class="ot">-&gt;</span> <span class="dt">Just</span> (<span class="fu">max</span> x y)</span></code></pre></div>
303</section>
304<section class="slide level1">
306<h2 id="полиморфные-инстансы">Полиморфные инстансы</h2>
307<div class="sourceCode" id="cb38"><pre class="sourceCode haskell fragment"><code class="sourceCode haskell"><span id="cb38-1"><a href="#cb38-1"></a><span class="kw">instance</span> <span class="dt">Ord</span> (<span class="dt">Maybe</span> a)</span></code></pre></div>
308<div class="sourceCode" id="cb39"><pre class="sourceCode haskell fragment"><code class="sourceCode haskell"><span id="cb39-1"><a href="#cb39-1"></a><span class="kw">instance</span> <span class="dt">Eq</span> (<span class="dt">Maybe</span> a)</span></code></pre></div>
309<div class="sourceCode" id="cb40"><pre class="sourceCode haskell fragment"><code class="sourceCode haskell"><span id="cb40-1"><a href="#cb40-1"></a><span class="kw">instance</span> <span class="dt">Eq</span> a <span class="ot">=&gt;</span> <span class="dt">Eq</span> (<span class="dt">Maybe</span> a) <span class="kw">where</span></span>
310<span id="cb40-2"><a href="#cb40-2"></a> (<span class="op">==</span>) <span class="dt">Nothing</span> <span class="dt">Nothing</span> <span class="ot">=</span> <span class="dt">True</span></span>
311<span id="cb40-3"><a href="#cb40-3"></a> (<span class="op">==</span>) (<span class="dt">Just</span> a) (<span class="dt">Just</span> b) <span class="ot">=</span> a <span class="op">==</span> b</span>
312<span id="cb40-4"><a href="#cb40-4"></a> _ <span class="op">==</span> _ <span class="ot">=</span> <span class="dt">False</span></span></code></pre></div>
313<div class="sourceCode" id="cb41"><pre class="sourceCode haskell fragment"><code class="sourceCode haskell"><span id="cb41-1"><a href="#cb41-1"></a><span class="kw">instance</span> <span class="dt">Ord</span> a <span class="ot">=&gt;</span> <span class="dt">Ord</span> (<span class="dt">Maybe</span> a) <span class="kw">where</span></span>
314<span id="cb41-2"><a href="#cb41-2"></a> <span class="co">-- Потому что мы хотим чтобы Nothing был меньше всех</span></span>
315<span id="cb41-3"><a href="#cb41-3"></a> <span class="dt">Nothing</span> <span class="op">&lt;=</span> _ <span class="ot">=</span> <span class="dt">True</span></span>
316<span id="cb41-4"><a href="#cb41-4"></a> (<span class="dt">Just</span> a) <span class="op">&lt;=</span> (<span class="dt">Just</span> b) <span class="ot">=</span> a <span class="op">&lt;=</span> b</span>
317<span id="cb41-5"><a href="#cb41-5"></a> (<span class="dt">Just</span> _) <span class="op">&lt;=</span> <span class="dt">Nothing</span> <span class="ot">=</span> <span class="dt">False</span></span></code></pre></div>
318</section>
319<section class="slide level1">
321<p>Что нам это дает?</p>
322<div class="sourceCode" id="cb42"><pre class="sourceCode haskell fragment"><code class="sourceCode haskell"><span id="cb42-1"><a href="#cb42-1"></a><span class="fu">maximum</span><span class="ot"> ::</span> <span class="dt">Ord</span> a <span class="ot">=&gt;</span> [a] <span class="ot">-&gt;</span> <span class="dt">Maybe</span> a</span>
323<span id="cb42-2"><a href="#cb42-2"></a><span class="fu">maximum</span> [] <span class="ot">=</span> <span class="dt">Nothing</span></span>
324<span id="cb42-3"><a href="#cb42-3"></a><span class="fu">maximum</span> (x <span class="op">:</span> xs) <span class="ot">=</span> <span class="kw">case</span> <span class="fu">maximum</span> xs <span class="kw">of</span></span>
325<span id="cb42-4"><a href="#cb42-4"></a> <span class="dt">Nothing</span> <span class="ot">-&gt;</span> <span class="dt">Just</span> x</span>
326<span id="cb42-5"><a href="#cb42-5"></a> <span class="dt">Just</span> y <span class="ot">-&gt;</span> <span class="dt">Just</span> (<span class="fu">max</span> x y)</span></code></pre></div>
327<div class="sourceCode" id="cb43"><pre class="sourceCode haskell fragment"><code class="sourceCode haskell"><span id="cb43-1"><a href="#cb43-1"></a><span class="fu">maximum</span><span class="ot"> ::</span> <span class="dt">Ord</span> a <span class="ot">=&gt;</span> [a] <span class="ot">-&gt;</span> <span class="dt">Maybe</span> a</span>
328<span id="cb43-2"><a href="#cb43-2"></a><span class="fu">maximum</span> [] <span class="ot">=</span> <span class="dt">Nothing</span></span>
329<span id="cb43-3"><a href="#cb43-3"></a><span class="fu">maximum</span> (x <span class="op">:</span> xs) <span class="ot">=</span> <span class="fu">max</span> (<span class="dt">Just</span> x) (<span class="fu">maximum</span> xs)</span></code></pre></div>
330</section>
331<section class="slide level1">
333<h2 id="моноид">Моноид</h2>
334<blockquote>
335<p>Моноид – полугруппа с нейтральным элементом</p>
336</blockquote>
337</section>
338<section class="slide level1">
340<h2 id="полугруппа">Полугруппа</h2>
341<div class="sourceCode" id="cb44"><pre class="sourceCode haskell fragment"><code class="sourceCode haskell"><span id="cb44-1"><a href="#cb44-1"></a><span class="kw">class</span> <span class="dt">Semigroup</span> s <span class="kw">where</span></span>
342<span id="cb44-2"><a href="#cb44-2"></a><span class="ot"> (&lt;&gt;) ::</span> s <span class="ot">-&gt;</span> s <span class="ot">-&gt;</span> s</span></code></pre></div>
343<div class="sourceCode" id="cb45"><pre class="sourceCode haskell fragment"><code class="sourceCode haskell"><span id="cb45-1"><a href="#cb45-1"></a><span class="kw">instance</span> <span class="dt">Semigroup</span> [x] <span class="kw">where</span></span>
344<span id="cb45-2"><a href="#cb45-2"></a> a <span class="op">&lt;&gt;</span> b <span class="ot">=</span> a <span class="op">++</span> b <span class="co">-- конкатенация списков</span></span></code></pre></div>
345<h2 id="моноид-1"><span class="fragment">Моноид</span></h2>
346<div class="sourceCode" id="cb46"><pre class="sourceCode haskell fragment"><code class="sourceCode haskell"><span id="cb46-1"><a href="#cb46-1"></a><span class="kw">class</span> <span class="dt">Semigroup</span> s <span class="ot">=&gt;</span> <span class="dt">Monoid</span> s <span class="kw">where</span></span>
347<span id="cb46-2"><a href="#cb46-2"></a><span class="ot"> mempty ::</span> s</span></code></pre></div>
348<div class="sourceCode" id="cb47"><pre class="sourceCode haskell fragment"><code class="sourceCode haskell"><span id="cb47-1"><a href="#cb47-1"></a><span class="kw">instance</span> <span class="dt">Monoid</span> [x] <span class="kw">where</span></span>
349<span id="cb47-2"><a href="#cb47-2"></a> <span class="fu">mempty</span> <span class="ot">=</span> []</span></code></pre></div>
350</section>
351<section class="slide level1">
353<p>“Схлопывает” список моноидов.</p>
354<div class="sourceCode" id="cb48"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb48-1"><a href="#cb48-1"></a><span class="ot">fold ::</span> <span class="dt">Monoid</span> m <span class="ot">=&gt;</span> [m] <span class="ot">-&gt;</span> m</span></code></pre></div>
355<div class="sourceCode" id="cb49"><pre class="sourceCode haskell fragment"><code class="sourceCode haskell"><span id="cb49-1"><a href="#cb49-1"></a>fold [] <span class="ot">=</span> <span class="fu">mempty</span></span>
356<span id="cb49-2"><a href="#cb49-2"></a>fold (x <span class="op">:</span> xs) <span class="ot">=</span> x <span class="op">&lt;&gt;</span> fold xs</span></code></pre></div>
357<div class="sourceCode" id="cb50"><pre class="sourceCode haskell fragment"><code class="sourceCode haskell"><span id="cb50-1"><a href="#cb50-1"></a>fold [[<span class="dv">1</span>, <span class="dv">3</span>, <span class="dv">5</span>], [<span class="dv">42</span>, <span class="dv">69</span>]]</span>
358<span id="cb50-2"><a href="#cb50-2"></a><span class="co">-- [1, 3, 5, 42, 69]</span></span></code></pre></div>
359</section>
360<section class="slide level1">
362<div class="sourceCode" id="cb51"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb51-1"><a href="#cb51-1"></a><span class="ot">fold ::</span> <span class="dt">Monoid</span> m <span class="ot">=&gt;</span> [m] <span class="ot">-&gt;</span> m</span>
363<span id="cb51-2"><a href="#cb51-2"></a>fold [] <span class="ot">=</span> <span class="fu">mempty</span></span>
364<span id="cb51-3"><a href="#cb51-3"></a>fold (x <span class="op">:</span> xs) <span class="ot">=</span> x <span class="op">&lt;&gt;</span> fold xs</span></code></pre></div>
365<div class="sourceCode" id="cb52"><pre class="sourceCode haskell fragment"><code class="sourceCode haskell"><span id="cb52-1"><a href="#cb52-1"></a>fold [<span class="dv">1</span>, <span class="dv">2</span>, <span class="dv">3</span>]</span>
366<span id="cb52-2"><a href="#cb52-2"></a><span class="co">-- Что должно произойти?</span></span></code></pre></div>
367</section>
368<section class="slide level1">
370<p>У целых чисел нет одного определения моноида.</p>
371<p><span class="fragment">Но мы можем определить свои типы!</span></p>
372<div class="sourceCode" id="cb53"><pre class="sourceCode haskell fragment"><code class="sourceCode haskell"><span id="cb53-1"><a href="#cb53-1"></a><span class="kw">data</span> <span class="dt">Sum</span> <span class="ot">=</span> <span class="dt">Sum</span> {<span class="ot"> unSum ::</span> <span class="dt">Int</span> }</span></code></pre></div>
373<div class="sourceCode" id="cb54"><pre class="sourceCode haskell fragment"><code class="sourceCode haskell"><span id="cb54-1"><a href="#cb54-1"></a><span class="kw">instance</span> <span class="dt">Semigroup</span> <span class="dt">Sum</span> <span class="kw">where</span></span>
374<span id="cb54-2"><a href="#cb54-2"></a> (<span class="dt">Sum</span> a) <span class="op">&lt;&gt;</span> (<span class="dt">Sum</span> b) <span class="ot">=</span> <span class="dt">Sum</span> (a <span class="op">+</span> b)</span></code></pre></div>
375<div class="sourceCode" id="cb55"><pre class="sourceCode haskell fragment"><code class="sourceCode haskell"><span id="cb55-1"><a href="#cb55-1"></a><span class="kw">instance</span> <span class="dt">Monoid</span> <span class="dt">Sum</span> <span class="kw">where</span></span>
376<span id="cb55-2"><a href="#cb55-2"></a> <span class="fu">mempty</span> <span class="ot">=</span> <span class="dt">Sum</span> <span class="dv">0</span></span></code></pre></div>
377<div class="sourceCode" id="cb56"><pre class="sourceCode haskell fragment"><code class="sourceCode haskell"><span id="cb56-1"><a href="#cb56-1"></a><span class="fu">map</span><span class="ot"> ::</span> (a <span class="ot">-&gt;</span> b) <span class="ot">-&gt;</span> [a] <span class="ot">-&gt;</span> [b]</span></code></pre></div>
378<div class="sourceCode" id="cb57"><pre class="sourceCode haskell fragment"><code class="sourceCode haskell"><span id="cb57-1"><a href="#cb57-1"></a><span class="fu">map</span> (<span class="op">+</span> <span class="dv">1</span>) [<span class="dv">1</span>, <span class="dv">2</span>, <span class="dv">3</span>]</span>
379<span id="cb57-2"><a href="#cb57-2"></a><span class="co">-- [2, 3, 4]</span></span></code></pre></div>
380<div class="sourceCode" id="cb58"><pre class="sourceCode haskell fragment"><code class="sourceCode haskell"><span id="cb58-1"><a href="#cb58-1"></a>(unSum <span class="op">.</span> fold <span class="op">.</span> <span class="fu">map</span> <span class="dt">Sum</span>) [<span class="dv">1</span>, <span class="dv">2</span>, <span class="dv">3</span>]</span>
381<span id="cb58-2"><a href="#cb58-2"></a><span class="co">-- 6</span></span></code></pre></div>
382</section>
383<section id="deriving" class="slide level1">
384<h1>Deriving</h1>
385<div class="sourceCode" id="cb59"><pre class="sourceCode haskell fragment"><code class="sourceCode haskell"><span id="cb59-1"><a href="#cb59-1"></a><span class="kw">class</span> <span class="dt">Show</span> a <span class="kw">where</span></span>
386<span id="cb59-2"><a href="#cb59-2"></a><span class="ot"> show ::</span> a <span class="ot">-&gt;</span> <span class="dt">String</span></span></code></pre></div>
387<div class="sourceCode" id="cb60"><pre class="sourceCode haskell fragment"><code class="sourceCode haskell"><span id="cb60-1"><a href="#cb60-1"></a><span class="kw">data</span> <span class="dt">Foo</span> <span class="ot">=</span> <span class="dt">Bar</span> <span class="dt">Int</span> <span class="dt">Int</span> <span class="dt">String</span></span>
388<span id="cb60-2"><a href="#cb60-2"></a> <span class="kw">deriving</span> <span class="dt">Show</span></span></code></pre></div>
389<div class="sourceCode" id="cb61"><pre class="sourceCode haskell fragment"><code class="sourceCode haskell"><span id="cb61-1"><a href="#cb61-1"></a><span class="fu">show</span> (<span class="dt">Bar</span> <span class="dv">1</span> <span class="dv">2</span> <span class="st">&quot;hello&quot;</span>)</span>
390<span id="cb61-2"><a href="#cb61-2"></a><span class="co">-- Bar 1 2 &quot;hello&quot;</span></span></code></pre></div>
391<div class="sourceCode" id="cb62"><pre class="sourceCode haskell fragment"><code class="sourceCode haskell"><span id="cb62-1"><a href="#cb62-1"></a><span class="kw">data</span> <span class="dt">Foo</span> <span class="ot">=</span> <span class="dt">Bar</span> <span class="dt">Int</span> <span class="dt">Int</span> <span class="dt">String</span></span>
392<span id="cb62-2"><a href="#cb62-2"></a> <span class="kw">deriving</span> (<span class="dt">Show</span>, <span class="dt">Eq</span>, <span class="dt">Ord</span>)</span></code></pre></div>
393<div class="sourceCode" id="cb63"><pre class="sourceCode haskell fragment"><code class="sourceCode haskell"><span id="cb63-1"><a href="#cb63-1"></a><span class="dt">Bar</span> <span class="dv">3</span> <span class="dv">10</span> <span class="st">&quot;hello&quot;</span> <span class="op">==</span> <span class="dt">Bar</span> <span class="dv">3</span> <span class="dv">10</span> <span class="st">&quot;hello&quot;</span></span>
394<span id="cb63-2"><a href="#cb63-2"></a><span class="co">-- True</span></span>
395<span id="cb63-3"><a href="#cb63-3"></a><span class="dt">Bar</span> <span class="dv">3</span> <span class="dv">10</span> <span class="st">&quot;hello&quot;</span> <span class="op">==</span> <span class="dt">Bar</span> <span class="dv">3</span> <span class="dv">10</span> <span class="st">&quot;oh no&quot;</span></span>
396<span id="cb63-4"><a href="#cb63-4"></a><span class="co">-- False</span></span></code></pre></div>
397<div class="sourceCode" id="cb64"><pre class="sourceCode haskell fragment"><code class="sourceCode haskell"><span id="cb64-1"><a href="#cb64-1"></a><span class="dt">Bar</span> <span class="dv">3</span> <span class="dv">10</span> <span class="st">&quot;hello&quot;</span> <span class="op">&lt;</span> <span class="dt">Bar</span> <span class="dv">4</span> <span class="op">-</span><span class="dv">1000</span> <span class="st">&quot;oh no&quot;</span></span>
398<span id="cb64-2"><a href="#cb64-2"></a><span class="co">-- True</span></span></code></pre></div>
399</section>
400<section class="slide level1">
402<h2 id="синонимы-типов">Синонимы типов</h2>
403<p><span class="fragment">Тип можно обозвать как-то по-другому чтобы код было удобнее читать.</span></p>
404<div class="sourceCode" id="cb65"><pre class="sourceCode haskell fragment"><code class="sourceCode haskell"><span id="cb65-1"><a href="#cb65-1"></a><span class="kw">type</span> <span class="dt">String</span> <span class="ot">=</span> [<span class="dt">Char</span>]</span></code></pre></div>
405<div class="sourceCode" id="cb66"><pre class="sourceCode haskell fragment"><code class="sourceCode haskell"><span id="cb66-1"><a href="#cb66-1"></a><span class="kw">type</span> <span class="dt">Age</span> <span class="ot">=</span> <span class="dt">Int</span></span>
406<span id="cb66-2"><a href="#cb66-2"></a><span class="kw">type</span> <span class="dt">Name</span> <span class="ot">=</span> <span class="dt">String</span></span></code></pre></div>
407<div class="sourceCode" id="cb67"><pre class="sourceCode haskell fragment"><code class="sourceCode haskell"><span id="cb67-1"><a href="#cb67-1"></a><span class="kw">data</span> <span class="dt">Person</span> <span class="ot">=</span> <span class="dt">Person</span> <span class="dt">Name</span> <span class="dt">Age</span></span></code></pre></div>
408<p><span class="fragment">Буквально эквивалентно тому чтобы сделать find and replace по коду.</span></p>
409</section>
410<section class="slide level1">
412<div class="sourceCode" id="cb68"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb68-1"><a href="#cb68-1"></a><span class="ot">scream ::</span> <span class="dt">String</span> <span class="ot">-&gt;</span> <span class="dt">String</span></span>
413<span id="cb68-2"><a href="#cb68-2"></a>scream <span class="ot">=</span> <span class="fu">map</span> <span class="fu">toUpper</span></span></code></pre></div>
414<div class="sourceCode" id="cb69"><pre class="sourceCode haskell fragment"><code class="sourceCode haskell"><span id="cb69-1"><a href="#cb69-1"></a><span class="kw">type</span> <span class="dt">Name</span> <span class="ot">=</span> <span class="dt">String</span></span></code></pre></div>
415<div class="sourceCode" id="cb70"><pre class="sourceCode haskell fragment"><code class="sourceCode haskell"><span id="cb70-1"><a href="#cb70-1"></a><span class="ot">name ::</span> <span class="dt">Name</span></span>
416<span id="cb70-2"><a href="#cb70-2"></a>name <span class="ot">=</span> <span class="st">&quot;Vasya&quot;</span></span>
417<span id="cb70-3"><a href="#cb70-3"></a></span>
418<span id="cb70-4"><a href="#cb70-4"></a><span class="co">-- This is fine.</span></span>
419<span id="cb70-5"><a href="#cb70-5"></a>scream name</span>
420<span id="cb70-6"><a href="#cb70-6"></a><span class="co">-- &quot;VASYA&quot;</span></span></code></pre></div>
421<p><span class="fragment">В функцию <code>capitalize</code> можно передать константу типа <code>Name</code> потому что <code>String</code> и <code>Name</code> это одно и то же.</span></p>
422</section>
423<section class="slide level1">
425<p><code>data</code> – новый тип</p>
426<p><code>type</code> – просто обозвали по-другому</p>
427</section>
428<section class="slide level1">
430<div class="sourceCode" id="cb71"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb71-1"><a href="#cb71-1"></a><span class="ot">fold ::</span> <span class="dt">Monoid</span> m <span class="ot">=&gt;</span> [m] <span class="ot">-&gt;</span> m</span>
431<span id="cb71-2"><a href="#cb71-2"></a>fold [] <span class="ot">=</span> <span class="fu">mempty</span></span>
432<span id="cb71-3"><a href="#cb71-3"></a>fold (x <span class="op">:</span> xs) <span class="ot">=</span> x <span class="op">&lt;&gt;</span> fold xs</span></code></pre></div>
433<div class="sourceCode" id="cb72"><pre class="sourceCode haskell fragment"><code class="sourceCode haskell"><span id="cb72-1"><a href="#cb72-1"></a>fold [<span class="st">&quot;Hello&quot;</span>, <span class="st">&quot;World&quot;</span>]</span>
434<span id="cb72-2"><a href="#cb72-2"></a><span class="co">-- &quot;HelloWorld&quot;</span></span>
435<span id="cb72-3"><a href="#cb72-3"></a><span class="co">--</span></span>
436<span id="cb72-4"><a href="#cb72-4"></a><span class="co">-- Потому что</span></span>
437<span id="cb72-5"><a href="#cb72-5"></a><span class="co">-- type String = [Char]</span></span></code></pre></div>
438</section>
439<section id="обработка-ошибок" class="slide level1">
440<h1>Обработка ошибок</h1>
441</section>
442<section class="slide level1">
444<div class="sourceCode" id="cb73"><pre class="sourceCode java"><code class="sourceCode java"><span id="cb73-1"><a href="#cb73-1"></a><span class="bu">TreeMap</span>&lt;<span class="bu">String</span>, <span class="bu">Integer</span>&gt; m = <span class="kw">new</span> <span class="bu">TreeMap</span>();</span>
445<span id="cb73-2"><a href="#cb73-2"></a>m.<span class="fu">put</span>(<span class="st">&quot;one&quot;</span>, <span class="dv">1</span>);</span>
446<span id="cb73-3"><a href="#cb73-3"></a>m.<span class="fu">put</span>(<span class="st">&quot;two&quot;</span>, <span class="dv">2</span>);</span>
447<span id="cb73-4"><a href="#cb73-4"></a>m.<span class="fu">put</span>(<span class="st">&quot;three&quot;</span>, <span class="dv">3</span>);</span></code></pre></div>
448<div class="sourceCode" id="cb74"><pre class="sourceCode java fragment"><code class="sourceCode java"><span id="cb74-1"><a href="#cb74-1"></a>m.<span class="fu">get</span>(<span class="st">&quot;one&quot;</span>);</span>
449<span id="cb74-2"><a href="#cb74-2"></a><span class="co">// 1</span></span></code></pre></div>
450<div class="sourceCode" id="cb75"><pre class="sourceCode java fragment"><code class="sourceCode java"><span id="cb75-1"><a href="#cb75-1"></a>m.<span class="fu">get</span>(<span class="st">&quot;five&quot;</span>);</span>
451<span id="cb75-2"><a href="#cb75-2"></a><span class="co">// null</span></span></code></pre></div>
452<div class="sourceCode" id="cb76"><pre class="sourceCode java fragment"><code class="sourceCode java"><span id="cb76-1"><a href="#cb76-1"></a><span class="kw">class</span> <span class="bu">TreeMap</span>&lt;K,V&gt; {</span>
453<span id="cb76-2"><a href="#cb76-2"></a> V <span class="fu">get</span>(K key) {</span>
454<span id="cb76-3"><a href="#cb76-3"></a> ...</span></code></pre></div>
455<p><span class="fragment">Неявный контекст ошибки ВЕЗДЕ.</span></p>
456</section>
457<section class="slide level1">
459<div class="sourceCode" id="cb77"><pre class="sourceCode java"><code class="sourceCode java"><span id="cb77-1"><a href="#cb77-1"></a><span class="kw">class</span> <span class="bu">TreeMap</span>&lt;K,V&gt; {</span>
460<span id="cb77-2"><a href="#cb77-2"></a> Pair&lt;V, <span class="bu">Boolean</span>&gt; <span class="fu">get</span>(K key) {</span>
461<span id="cb77-3"><a href="#cb77-3"></a> ...</span></code></pre></div>
462<div class="sourceCode" id="cb78"><pre class="sourceCode java fragment"><code class="sourceCode java"><span id="cb78-1"><a href="#cb78-1"></a>Pair&lt;<span class="bu">Integer</span>, <span class="bu">Boolean</span>&gt; result = m.<span class="fu">get</span>(<span class="st">&quot;one&quot;</span>);</span>
463<span id="cb78-2"><a href="#cb78-2"></a></span>
464<span id="cb78-3"><a href="#cb78-3"></a><span class="kw">if</span> (result.<span class="fu">second</span>()) {</span>
465<span id="cb78-4"><a href="#cb78-4"></a> <span class="fu">print</span>(m.<span class="fu">first</span>());</span>
466<span id="cb78-5"><a href="#cb78-5"></a>} <span class="kw">else</span> {</span>
467<span id="cb78-6"><a href="#cb78-6"></a> <span class="fu">print</span>(<span class="st">&quot;oh no&quot;</span>);</span>
468<span id="cb78-7"><a href="#cb78-7"></a>}</span>
469<span id="cb78-8"><a href="#cb78-8"></a><span class="co">// 1</span></span></code></pre></div>
470<div class="sourceCode" id="cb79"><pre class="sourceCode java fragment"><code class="sourceCode java"><span id="cb79-1"><a href="#cb79-1"></a>Pair&lt;<span class="bu">Integer</span>, <span class="bu">Boolean</span>&gt; result = m.<span class="fu">get</span>(<span class="st">&quot;five&quot;</span>);</span>
471<span id="cb79-2"><a href="#cb79-2"></a></span>
472<span id="cb79-3"><a href="#cb79-3"></a><span class="kw">if</span> (result.<span class="fu">second</span>()) {</span>
473<span id="cb79-4"><a href="#cb79-4"></a> <span class="fu">print</span>(m.<span class="fu">first</span>());</span>
474<span id="cb79-5"><a href="#cb79-5"></a>} <span class="kw">else</span> {</span>
475<span id="cb79-6"><a href="#cb79-6"></a> <span class="fu">print</span>(<span class="st">&quot;oh no&quot;</span>);</span>
476<span id="cb79-7"><a href="#cb79-7"></a>}</span>
477<span id="cb79-8"><a href="#cb79-8"></a><span class="co">// oh no</span></span></code></pre></div>
478</section>
479<section class="slide level1">
481<div class="sourceCode" id="cb80"><pre class="sourceCode java"><code class="sourceCode java"><span id="cb80-1"><a href="#cb80-1"></a><span class="kw">class</span> <span class="bu">TreeMap</span>&lt;K,V&gt; {</span>
482<span id="cb80-2"><a href="#cb80-2"></a> V <span class="fu">get</span>(K key) <span class="kw">throws</span> NoElementException {</span>
483<span id="cb80-3"><a href="#cb80-3"></a> ...</span></code></pre></div>
484<div class="sourceCode" id="cb81"><pre class="sourceCode java fragment"><code class="sourceCode java"><span id="cb81-1"><a href="#cb81-1"></a><span class="kw">try</span> {</span>
485<span id="cb81-2"><a href="#cb81-2"></a> <span class="fu">print</span>(m.<span class="fu">get</span>(<span class="st">&quot;five&quot;</span>));</span>
486<span id="cb81-3"><a href="#cb81-3"></a>} <span class="kw">catch</span> (NoElementException e) {</span>
487<span id="cb81-4"><a href="#cb81-4"></a> <span class="fu">print</span>(<span class="st">&quot;oh no&quot;</span>);</span>
488<span id="cb81-5"><a href="#cb81-5"></a>}</span>
489<span id="cb81-6"><a href="#cb81-6"></a><span class="co">// oh no</span></span></code></pre></div>
490</section>
491<section class="slide level1">
493<div class="sourceCode" id="cb82"><pre class="sourceCode java"><code class="sourceCode java"><span id="cb82-1"><a href="#cb82-1"></a><span class="kw">class</span> Optional&lt;T&gt; {</span>
494<span id="cb82-2"><a href="#cb82-2"></a> ...</span></code></pre></div>
495<div class="sourceCode" id="cb83"><pre class="sourceCode java fragment"><code class="sourceCode java"><span id="cb83-1"><a href="#cb83-1"></a><span class="kw">class</span> <span class="bu">TreeMap</span>&lt;K,V&gt; {</span>
496<span id="cb83-2"><a href="#cb83-2"></a> Optional&lt;V&gt; <span class="fu">get</span>(K key) {</span>
497<span id="cb83-3"><a href="#cb83-3"></a> ...</span></code></pre></div>
498</section>
499<section class="slide level1">
501<div class="sourceCode" id="cb84"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb84-1"><a href="#cb84-1"></a><span class="ot">m ::</span> <span class="dt">Map</span> <span class="dt">String</span> <span class="dt">Int</span></span>
502<span id="cb84-2"><a href="#cb84-2"></a>m <span class="ot">=</span> fromList [(<span class="st">&quot;one&quot;</span>, <span class="dv">1</span>), (<span class="st">&quot;two&quot;</span>, <span class="dv">2</span>), (<span class="st">&quot;three&quot;</span>, <span class="dv">3</span>)]</span></code></pre></div>
503<div class="sourceCode" id="cb85"><pre class="sourceCode haskell fragment"><code class="sourceCode haskell"><span id="cb85-1"><a href="#cb85-1"></a><span class="kw">data</span> <span class="dt">Maybe</span> a <span class="ot">=</span> <span class="dt">Just</span> a <span class="op">|</span> <span class="dt">Nothing</span></span></code></pre></div>
504<div class="sourceCode" id="cb86"><pre class="sourceCode haskell fragment"><code class="sourceCode haskell"><span id="cb86-1"><a href="#cb86-1"></a><span class="fu">lookup</span><span class="ot"> ::</span> k <span class="ot">-&gt;</span> <span class="dt">Map</span> k v <span class="ot">-&gt;</span> <span class="dt">Maybe</span> v</span></code></pre></div>
505<div class="sourceCode" id="cb87"><pre class="sourceCode haskell fragment"><code class="sourceCode haskell"><span id="cb87-1"><a href="#cb87-1"></a><span class="fu">lookup</span> <span class="st">&quot;one&quot;</span> m</span>
506<span id="cb87-2"><a href="#cb87-2"></a><span class="co">-- Just 1</span></span></code></pre></div>
507<div class="sourceCode" id="cb88"><pre class="sourceCode haskell fragment"><code class="sourceCode haskell"><span id="cb88-1"><a href="#cb88-1"></a><span class="fu">lookup</span> <span class="st">&quot;five&quot;</span> m</span>
508<span id="cb88-2"><a href="#cb88-2"></a><span class="co">-- Nothing</span></span></code></pre></div>
509<div class="sourceCode" id="cb89"><pre class="sourceCode haskell fragment"><code class="sourceCode haskell"><span id="cb89-1"><a href="#cb89-1"></a><span class="kw">case</span> <span class="fu">lookup</span> <span class="st">&quot;one&quot;</span> m <span class="kw">of</span></span>
510<span id="cb89-2"><a href="#cb89-2"></a> <span class="dt">Just</span> n <span class="ot">-&gt;</span> <span class="op">...</span></span>
511<span id="cb89-3"><a href="#cb89-3"></a> <span class="dt">Nothing</span> <span class="ot">-&gt;</span> <span class="op">...</span></span></code></pre></div>
512</section>
513<section class="slide level1">
515<div class="sourceCode" id="cb90"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb90-1"><a href="#cb90-1"></a><span class="kw">data</span> <span class="dt">Either</span> a b <span class="ot">=</span> <span class="dt">Left</span> a <span class="op">|</span> <span class="dt">Right</span> b</span></code></pre></div>
516<div class="sourceCode" id="cb91"><pre class="sourceCode haskell fragment"><code class="sourceCode haskell"><span id="cb91-1"><a href="#cb91-1"></a><span class="fu">lookup</span><span class="ot"> ::</span> k <span class="ot">-&gt;</span> <span class="dt">Map</span> k v <span class="ot">-&gt;</span> <span class="dt">Either</span> <span class="dt">MapError</span> v</span></code></pre></div>
517<div class="sourceCode" id="cb92"><pre class="sourceCode haskell fragment"><code class="sourceCode haskell"><span id="cb92-1"><a href="#cb92-1"></a><span class="ot">makePayment ::</span> <span class="dt">Card</span> <span class="ot">-&gt;</span> <span class="dt">Amount</span> <span class="ot">-&gt;</span> <span class="dt">Either</span> <span class="dt">PaymentError</span> <span class="dt">Card</span></span></code></pre></div>
518<div class="sourceCode" id="cb93"><pre class="sourceCode haskell fragment"><code class="sourceCode haskell"><span id="cb93-1"><a href="#cb93-1"></a>makePayment card amount <span class="ot">=</span></span>
519<span id="cb93-2"><a href="#cb93-2"></a> <span class="kw">if</span> balance card <span class="op">&gt;=</span> amount</span>
520<span id="cb93-3"><a href="#cb93-3"></a> <span class="kw">then</span> <span class="dt">Right</span> (withdraw amount card)</span>
521<span id="cb93-4"><a href="#cb93-4"></a> <span class="kw">else</span> <span class="dt">Left</span> <span class="dt">InsufficientFunds</span></span></code></pre></div>
522</section>
523<section class="slide level1">
525<div class="sourceCode" id="cb94"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb94-1"><a href="#cb94-1"></a><span class="co">-- Обновляет аккаунт пользователя новой информацией о карте</span></span>
526<span id="cb94-2"><a href="#cb94-2"></a><span class="ot">updateAccount ::</span> <span class="dt">Account</span> <span class="ot">-&gt;</span> <span class="dt">Card</span> <span class="ot">-&gt;</span> <span class="dt">Account</span></span></code></pre></div>
527<div class="sourceCode" id="cb95"><pre class="sourceCode haskell fragment"><code class="sourceCode haskell"><span id="cb95-1"><a href="#cb95-1"></a><span class="ot">makePayment ::</span> <span class="dt">Card</span> <span class="ot">-&gt;</span> <span class="dt">Amount</span> <span class="ot">-&gt;</span> <span class="dt">Either</span> <span class="dt">PaymentError</span> <span class="dt">Card</span></span></code></pre></div>
528<div class="sourceCode" id="cb96"><pre class="sourceCode haskell fragment"><code class="sourceCode haskell"><span id="cb96-1"><a href="#cb96-1"></a>card <span class="ot">=</span> creditCard account</span>
529<span id="cb96-2"><a href="#cb96-2"></a></span>
530<span id="cb96-3"><a href="#cb96-3"></a><span class="ot">newAcccount ::</span> <span class="dt">Either</span> <span class="dt">PaymentError</span> <span class="dt">Account</span></span>
531<span id="cb96-4"><a href="#cb96-4"></a>newAcccount <span class="ot">=</span></span>
532<span id="cb96-5"><a href="#cb96-5"></a> updateAccount account (makePayment card (<span class="dt">RUB</span> <span class="dv">150</span>))</span></code></pre></div>
533<div class="sourceCode" id="cb97"><pre class="sourceCode haskell fragment"><code class="sourceCode haskell"><span id="cb97-1"><a href="#cb97-1"></a>newAcccount <span class="ot">=</span></span>
534<span id="cb97-2"><a href="#cb97-2"></a> updateAccount account (makePayment card (<span class="dt">RUB</span> <span class="dv">150</span>))</span>
535<span id="cb97-3"><a href="#cb97-3"></a><span class="co">-- (Card -&gt; Account) (Either PaymentError Card)</span></span></code></pre></div>
536<div class="sourceCode" id="cb98"><pre class="sourceCode haskell fragment"><code class="sourceCode haskell"><span id="cb98-1"><a href="#cb98-1"></a>newAcccount <span class="ot">=</span></span>
537<span id="cb98-2"><a href="#cb98-2"></a> <span class="kw">case</span> makePayment card (<span class="dt">RUB</span> <span class="dv">150</span>) <span class="kw">of</span></span>
538<span id="cb98-3"><a href="#cb98-3"></a> <span class="dt">Left</span> e <span class="ot">-&gt;</span> <span class="dt">Left</span> e</span>
539<span id="cb98-4"><a href="#cb98-4"></a> <span class="dt">Right</span> c <span class="ot">-&gt;</span> updateAccount account c</span></code></pre></div>
540</section>
541<section class="slide level1">
543<div class="sourceCode" id="cb99"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb99-1"><a href="#cb99-1"></a>newAcccount <span class="ot">=</span></span>
544<span id="cb99-2"><a href="#cb99-2"></a> updateAccount account (makePayment card (<span class="dt">RUB</span> <span class="dv">150</span>))</span>
545<span id="cb99-3"><a href="#cb99-3"></a><span class="co">-- (Card -&gt; Account) (Either PaymentError Card)</span></span></code></pre></div>
546<div class="sourceCode" id="cb100"><pre class="sourceCode haskell fragment"><code class="sourceCode haskell"><span id="cb100-1"><a href="#cb100-1"></a>newAcccount <span class="ot">=</span></span>
547<span id="cb100-2"><a href="#cb100-2"></a> magic (updateAccount account) (makePayment card (<span class="dt">RUB</span> <span class="dv">150</span>))</span>
548<span id="cb100-3"><a href="#cb100-3"></a><span class="co">-- | (Card -&gt; Account) (Either PaymentError Card)</span></span>
549<span id="cb100-4"><a href="#cb100-4"></a><span class="co">-- |</span></span>
550<span id="cb100-5"><a href="#cb100-5"></a><span class="co">-- (Card -&gt; Account)</span></span>
551<span id="cb100-6"><a href="#cb100-6"></a><span class="co">-- -&gt; (Either PaymentError Card</span></span>
552<span id="cb100-7"><a href="#cb100-7"></a><span class="co">-- -&gt; Either PaymentError Account)</span></span></code></pre></div>
553</section>
554<section class="slide level1">
556<h2 id="lists">Lists!</h2>
557<div class="sourceCode" id="cb101"><pre class="sourceCode haskell fragment"><code class="sourceCode haskell"><span id="cb101-1"><a href="#cb101-1"></a><span class="fu">map</span><span class="ot"> ::</span> (a <span class="ot">-&gt;</span> b) <span class="ot">-&gt;</span> [a] <span class="ot">-&gt;</span> [b]</span></code></pre></div>
558<div class="sourceCode" id="cb102"><pre class="sourceCode haskell fragment"><code class="sourceCode haskell"><span id="cb102-1"><a href="#cb102-1"></a><span class="fu">map</span><span class="ot"> ::</span> (a <span class="ot">-&gt;</span> b) <span class="ot">-&gt;</span> ([a] <span class="ot">-&gt;</span> [b])</span></code></pre></div>
559<div class="sourceCode" id="cb103"><pre class="sourceCode haskell fragment"><code class="sourceCode haskell"><span id="cb103-1"><a href="#cb103-1"></a><span class="ot">magic ::</span></span>
560<span id="cb103-2"><a href="#cb103-2"></a> (<span class="dt">Card</span> <span class="ot">-&gt;</span> <span class="dt">Account</span>) <span class="ot">-&gt;</span></span>
561<span id="cb103-3"><a href="#cb103-3"></a> ( (<span class="dt">Either</span> <span class="dt">PaymentError</span>) <span class="dt">Card</span> <span class="ot">-&gt;</span></span>
562<span id="cb103-4"><a href="#cb103-4"></a> (<span class="dt">Either</span> <span class="dt">PaymentError</span>) <span class="dt">Account</span></span>
563<span id="cb103-5"><a href="#cb103-5"></a> )</span></code></pre></div>
564<div class="sourceCode" id="cb104"><pre class="sourceCode haskell fragment"><code class="sourceCode haskell"><span id="cb104-1"><a href="#cb104-1"></a><span class="kw">type</span> <span class="dt">F</span> <span class="ot">=</span> <span class="dt">Either</span> <span class="dt">PaymentError</span></span></code></pre></div>
565<div class="sourceCode" id="cb105"><pre class="sourceCode haskell fragment"><code class="sourceCode haskell"><span id="cb105-1"><a href="#cb105-1"></a><span class="ot">magic ::</span> (<span class="dt">Card</span> <span class="ot">-&gt;</span> <span class="dt">Account</span>) <span class="ot">-&gt;</span> (<span class="dt">F</span> <span class="dt">Card</span> <span class="ot">-&gt;</span> <span class="dt">F</span> <span class="dt">Account</span>)</span></code></pre></div>
566</section>
567<section class="slide level1">
569<div class="sourceCode" id="cb106"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb106-1"><a href="#cb106-1"></a><span class="ot">magic ::</span> (<span class="dt">Card</span> <span class="ot">-&gt;</span> <span class="dt">Account</span>) <span class="ot">-&gt;</span> (<span class="dt">F</span> <span class="dt">Card</span> <span class="ot">-&gt;</span> <span class="dt">F</span> <span class="dt">Account</span>)</span></code></pre></div>
570<p><span class="fragment">А мы можем обобщить <code>F</code>?</span></p>
571<div class="sourceCode" id="cb107"><pre class="sourceCode haskell fragment"><code class="sourceCode haskell"><span id="cb107-1"><a href="#cb107-1"></a><span class="fu">fmap</span> <span class="ot">::</span></span>
572<span id="cb107-2"><a href="#cb107-2"></a> <span class="dt">Functor</span> f <span class="ot">=&gt;</span></span>
573<span id="cb107-3"><a href="#cb107-3"></a> (<span class="dt">Card</span> <span class="ot">-&gt;</span> <span class="dt">Account</span>) <span class="ot">-&gt;</span></span>
574<span id="cb107-4"><a href="#cb107-4"></a> (f <span class="dt">Card</span> <span class="ot">-&gt;</span> f <span class="dt">Account</span>)</span></code></pre></div>
575</section>
576<section id="functor" class="slide level1">
577<h1>Functor!</h1>
578<p><img data-src="images/fmap1.png" class="fragment" width="450" /></p>
579<p><img data-src="images/fmap2.png" class="fragment" width="450" /></p>
580</section>
581<section class="slide level1">
583<div class="sourceCode" id="cb108"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb108-1"><a href="#cb108-1"></a><span class="kw">class</span> <span class="dt">Functor</span> f <span class="kw">where</span></span>
584<span id="cb108-2"><a href="#cb108-2"></a><span class="ot"> fmap ::</span> (a <span class="ot">-&gt;</span> b) <span class="ot">-&gt;</span> f a <span class="ot">-&gt;</span> f b</span></code></pre></div>
585<div class="sourceCode" id="cb109"><pre class="sourceCode haskell fragment"><code class="sourceCode haskell"><span id="cb109-1"><a href="#cb109-1"></a><span class="kw">class</span> <span class="dt">Functor</span> [] <span class="kw">where</span></span>
586<span id="cb109-2"><a href="#cb109-2"></a><span class="ot"> fmap ::</span> (a <span class="ot">-&gt;</span> b) <span class="ot">-&gt;</span> [a] <span class="ot">-&gt;</span> [b]</span>
587<span id="cb109-3"><a href="#cb109-3"></a> <span class="fu">fmap</span> _ [] <span class="ot">=</span> []</span>
588<span id="cb109-4"><a href="#cb109-4"></a> <span class="fu">fmap</span> f (x <span class="op">:</span> xs) <span class="ot">=</span> f x <span class="op">:</span> <span class="fu">fmap</span> f xs</span></code></pre></div>
589<div class="sourceCode" id="cb110"><pre class="sourceCode haskell fragment"><code class="sourceCode haskell"><span id="cb110-1"><a href="#cb110-1"></a><span class="kw">class</span> <span class="dt">Functor</span> <span class="dt">Maybe</span> <span class="kw">where</span></span>
590<span id="cb110-2"><a href="#cb110-2"></a><span class="ot"> fmap ::</span> (a <span class="ot">-&gt;</span> b) <span class="ot">-&gt;</span> <span class="dt">Maybe</span> a <span class="ot">-&gt;</span> <span class="dt">Maybe</span> b</span>
591<span id="cb110-3"><a href="#cb110-3"></a> <span class="fu">fmap</span> _ <span class="dt">Nothing</span> <span class="ot">=</span> <span class="dt">Nothing</span></span>
592<span id="cb110-4"><a href="#cb110-4"></a> <span class="fu">fmap</span> f (<span class="dt">Just</span> x) <span class="ot">=</span> <span class="dt">Just</span> (f x)</span></code></pre></div>
593<div class="sourceCode" id="cb111"><pre class="sourceCode haskell fragment"><code class="sourceCode haskell"><span id="cb111-1"><a href="#cb111-1"></a><span class="kw">class</span> <span class="dt">Functor</span> (<span class="dt">Either</span> e) <span class="kw">where</span></span>
594<span id="cb111-2"><a href="#cb111-2"></a><span class="ot"> fmap ::</span> (a <span class="ot">-&gt;</span> b) <span class="ot">-&gt;</span> <span class="dt">Either</span> e a <span class="ot">-&gt;</span> <span class="dt">Either</span> e b</span>
595<span id="cb111-3"><a href="#cb111-3"></a> <span class="fu">fmap</span> _ (<span class="dt">Left</span> e) <span class="ot">=</span> <span class="dt">Left</span> e</span>
596<span id="cb111-4"><a href="#cb111-4"></a> <span class="fu">fmap</span> f (<span class="dt">Right</span> x) <span class="ot">=</span> <span class="dt">Right</span> (f x)</span></code></pre></div>
597</section>
598<section class="slide level1">
600<div class="sourceCode" id="cb112"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb112-1"><a href="#cb112-1"></a><span class="ot">updateAccount ::</span> <span class="dt">Account</span> <span class="ot">-&gt;</span> <span class="dt">Card</span> <span class="ot">-&gt;</span> <span class="dt">Account</span></span>
601<span id="cb112-2"><a href="#cb112-2"></a><span class="ot">makePayment ::</span> <span class="dt">Card</span> <span class="ot">-&gt;</span> <span class="dt">Amount</span> <span class="ot">-&gt;</span> <span class="dt">Either</span> <span class="dt">PaymentError</span> <span class="dt">Card</span></span>
602<span id="cb112-3"><a href="#cb112-3"></a></span>
603<span id="cb112-4"><a href="#cb112-4"></a><span class="ot">newAcccount ::</span> <span class="dt">Either</span> <span class="dt">PaymentError</span> <span class="dt">Account</span></span>
604<span id="cb112-5"><a href="#cb112-5"></a>newAcccount <span class="ot">=</span></span>
605<span id="cb112-6"><a href="#cb112-6"></a> <span class="fu">fmap</span> (updateAccount account) (makePayment card (<span class="dt">RUB</span> <span class="dv">150</span>))</span></code></pre></div>
606</section>
607<section class="slide level1">
609<div class="sourceCode" id="cb113"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb113-1"><a href="#cb113-1"></a><span class="kw">class</span> <span class="dt">Functor</span> f <span class="kw">where</span></span>
610<span id="cb113-2"><a href="#cb113-2"></a><span class="ot"> fmap ::</span> (a <span class="ot">-&gt;</span> b) <span class="ot">-&gt;</span> f a <span class="ot">-&gt;</span> f b</span></code></pre></div>
611<div class="sourceCode" id="cb114"><pre class="sourceCode haskell fragment"><code class="sourceCode haskell"><span id="cb114-1"><a href="#cb114-1"></a><span class="kw">class</span> <span class="dt">Functor</span> (x <span class="ot">-&gt;</span>) <span class="kw">where</span></span>
612<span id="cb114-2"><a href="#cb114-2"></a><span class="ot"> fmap ::</span> (a <span class="ot">-&gt;</span> b) <span class="ot">-&gt;</span> (x <span class="ot">-&gt;</span> a) <span class="ot">-&gt;</span> (x <span class="ot">-&gt;</span> b)</span>
613<span id="cb114-3"><a href="#cb114-3"></a> <span class="fu">fmap</span> (<span class="ot">f ::</span> a <span class="ot">-&gt;</span> b) (<span class="ot">g ::</span> x <span class="ot">-&gt;</span> a) <span class="ot">=</span> \(<span class="ot">u ::</span> x) <span class="ot">-&gt;</span> f (g u)</span></code></pre></div>
614<div class="sourceCode" id="cb115"><pre class="sourceCode haskell fragment"><code class="sourceCode haskell"><span id="cb115-1"><a href="#cb115-1"></a> <span class="fu">fmap</span> (<span class="ot">f ::</span> a <span class="ot">-&gt;</span> b) (<span class="ot">g ::</span> x <span class="ot">-&gt;</span> a) <span class="ot">=</span> f <span class="op">.</span> g</span></code></pre></div>
615<div class="sourceCode" id="cb116"><pre class="sourceCode haskell fragment"><code class="sourceCode haskell"><span id="cb116-1"><a href="#cb116-1"></a> <span class="fu">fmap</span> <span class="ot">=</span> (<span class="op">.</span>)</span></code></pre></div>
616</section>
617<section class="slide level1">
619<h2 id="functor-monoid">Functor + Monoid</h2>
620<h2 id="alternative"><span class="fragment">= Alternative!</span></h2>
621<div class="sourceCode" id="cb117"><pre class="sourceCode haskell fragment"><code class="sourceCode haskell"><span id="cb117-1"><a href="#cb117-1"></a><span class="kw">class</span> <span class="dt">Monoid</span> s <span class="kw">where</span></span>
622<span id="cb117-2"><a href="#cb117-2"></a><span class="ot"> (&lt;&gt;) ::</span> s <span class="ot">-&gt;</span> s <span class="ot">-&gt;</span> s</span>
623<span id="cb117-3"><a href="#cb117-3"></a><span class="ot"> mempty ::</span> s</span></code></pre></div>
624<div class="sourceCode" id="cb118"><pre class="sourceCode haskell fragment"><code class="sourceCode haskell"><span id="cb118-1"><a href="#cb118-1"></a><span class="ot">foo ::</span> f a <span class="ot">-&gt;</span> f a <span class="ot">-&gt;</span> f a</span></code></pre></div>
625<div class="sourceCode" id="cb119"><pre class="sourceCode haskell fragment"><code class="sourceCode haskell"><span id="cb119-1"><a href="#cb119-1"></a><span class="kw">class</span> <span class="dt">Functor</span> f <span class="ot">=&gt;</span> <span class="dt">Alternative</span> f <span class="kw">where</span></span>
626<span id="cb119-2"><a href="#cb119-2"></a><span class="ot"> (&lt;|&gt;) ::</span> f a <span class="ot">-&gt;</span> f a <span class="ot">-&gt;</span> f a</span>
627<span id="cb119-3"><a href="#cb119-3"></a><span class="ot"> empty ::</span> f a</span></code></pre></div>
628</section>
629<section class="slide level1">
631<div class="sourceCode" id="cb120"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb120-1"><a href="#cb120-1"></a><span class="kw">class</span> <span class="dt">Functor</span> f <span class="ot">=&gt;</span> <span class="dt">Alternative</span> f <span class="kw">where</span></span>
632<span id="cb120-2"><a href="#cb120-2"></a><span class="ot"> (&lt;|&gt;) ::</span> f a <span class="ot">-&gt;</span> f a <span class="ot">-&gt;</span> f a</span>
633<span id="cb120-3"><a href="#cb120-3"></a><span class="ot"> empty ::</span> f a</span></code></pre></div>
634<div class="sourceCode" id="cb121"><pre class="sourceCode haskell fragment"><code class="sourceCode haskell"><span id="cb121-1"><a href="#cb121-1"></a><span class="kw">instance</span> <span class="dt">Alternative</span> <span class="dt">Maybe</span> <span class="kw">where</span></span>
635<span id="cb121-2"><a href="#cb121-2"></a> (<span class="dt">Just</span> x) <span class="op">&lt;|&gt;</span> _ <span class="ot">=</span> <span class="dt">Just</span> x</span>
636<span id="cb121-3"><a href="#cb121-3"></a> <span class="dt">Nothing</span> <span class="op">&lt;|&gt;</span> y <span class="ot">=</span> y</span>
637<span id="cb121-4"><a href="#cb121-4"></a></span>
638<span id="cb121-5"><a href="#cb121-5"></a> empty <span class="ot">=</span> <span class="dt">Nothing</span></span></code></pre></div>
639<div class="sourceCode" id="cb122"><pre class="sourceCode haskell fragment"><code class="sourceCode haskell"><span id="cb122-1"><a href="#cb122-1"></a><span class="dt">Just</span> <span class="dv">42</span> <span class="op">&lt;|&gt;</span> <span class="dt">Just</span> <span class="dv">69</span></span>
640<span id="cb122-2"><a href="#cb122-2"></a><span class="co">-- Just 42</span></span></code></pre></div>
641<div class="sourceCode" id="cb123"><pre class="sourceCode haskell fragment"><code class="sourceCode haskell"><span id="cb123-1"><a href="#cb123-1"></a><span class="dt">Nothing</span> <span class="op">&lt;|&gt;</span> <span class="dt">Just</span> <span class="dv">69</span></span>
642<span id="cb123-2"><a href="#cb123-2"></a><span class="co">-- Just 69</span></span></code></pre></div>
643</section>
644<section class="slide level1">
646<div class="sourceCode" id="cb124"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb124-1"><a href="#cb124-1"></a><span class="kw">instance</span> <span class="dt">Monoid</span> e <span class="ot">=&gt;</span> <span class="dt">Alternative</span> (<span class="dt">Either</span> e) <span class="kw">where</span></span>
647<span id="cb124-2"><a href="#cb124-2"></a> (<span class="dt">Right</span> x) <span class="op">&lt;|&gt;</span> _ <span class="ot">=</span> <span class="dt">Right</span> x</span>
648<span id="cb124-3"><a href="#cb124-3"></a> _ <span class="op">&lt;|&gt;</span> y <span class="ot">=</span> y</span>
649<span id="cb124-4"><a href="#cb124-4"></a> empty <span class="ot">=</span> <span class="dt">Left</span> <span class="fu">mempty</span></span></code></pre></div>
650<div class="sourceCode" id="cb125"><pre class="sourceCode haskell fragment"><code class="sourceCode haskell"><span id="cb125-1"><a href="#cb125-1"></a><span class="dt">Left</span> <span class="st">&quot;oh no&quot;</span> <span class="op">&lt;|&gt;</span> <span class="dt">Right</span> <span class="dv">8</span></span>
651<span id="cb125-2"><a href="#cb125-2"></a><span class="co">-- Right 8</span></span></code></pre></div>
652<div class="sourceCode" id="cb126"><pre class="sourceCode haskell fragment"><code class="sourceCode haskell"><span id="cb126-1"><a href="#cb126-1"></a><span class="dt">Right</span> <span class="dv">42</span> <span class="op">&lt;|&gt;</span> <span class="dt">Right</span> <span class="dv">8</span></span>
653<span id="cb126-2"><a href="#cb126-2"></a><span class="co">-- Right 42</span></span></code></pre></div>
654<div class="sourceCode" id="cb127"><pre class="sourceCode haskell fragment"><code class="sourceCode haskell"><span id="cb127-1"><a href="#cb127-1"></a><span class="ot">makePayment ::</span> <span class="dt">Card</span> <span class="ot">-&gt;</span> <span class="dt">Amount</span> <span class="ot">-&gt;</span> <span class="dt">Either</span> <span class="dt">PaymentError</span> <span class="dt">Card</span></span></code></pre></div>
655<div class="sourceCode" id="cb128"><pre class="sourceCode haskell fragment"><code class="sourceCode haskell"><span id="cb128-1"><a href="#cb128-1"></a>makePayment card1 (<span class="dt">Rub</span> <span class="dv">150</span>) <span class="op">&lt;|&gt;</span> makePayment card2 (<span class="dt">Rub</span> <span class="dv">150</span>)</span></code></pre></div>
656</section>
657<section class="slide level1">
659<div class="sourceCode" id="cb129"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb129-1"><a href="#cb129-1"></a><span class="kw">instance</span> <span class="dt">Alternative</span> [] <span class="kw">where</span></span>
660<span id="cb129-2"><a href="#cb129-2"></a> xs <span class="op">&lt;|&gt;</span> ys <span class="ot">=</span> xs <span class="op">++</span> ys</span>
661<span id="cb129-3"><a href="#cb129-3"></a> empty <span class="ot">=</span> []</span></code></pre></div>
662<div class="sourceCode" id="cb130"><pre class="sourceCode haskell fragment"><code class="sourceCode haskell"><span id="cb130-1"><a href="#cb130-1"></a><span class="kw">class</span> <span class="dt">Applicative</span> f <span class="ot">=&gt;</span> <span class="dt">Alternative</span> f <span class="kw">where</span> <span class="op">...</span></span></code></pre></div>
663<div class="sourceCode" id="cb131"><pre class="sourceCode haskell fragment"><code class="sourceCode haskell"><span id="cb131-1"><a href="#cb131-1"></a><span class="kw">class</span> <span class="dt">Functor</span> f <span class="ot">=&gt;</span> <span class="dt">Applicative</span> f <span class="kw">where</span></span>
664<span id="cb131-2"><a href="#cb131-2"></a><span class="ot"> pure ::</span> a <span class="ot">-&gt;</span> f a</span>
665<span id="cb131-3"><a href="#cb131-3"></a> <span class="op">...</span></span></code></pre></div>
666<div class="sourceCode" id="cb132"><pre class="sourceCode haskell fragment"><code class="sourceCode haskell"><span id="cb132-1"><a href="#cb132-1"></a><span class="ot">mult ::</span> <span class="dt">Alternative</span> f <span class="ot">=&gt;</span> <span class="dt">Int</span> <span class="ot">-&gt;</span> f <span class="dt">Int</span></span>
667<span id="cb132-2"><a href="#cb132-2"></a>mult n <span class="ot">=</span> mult&#39; n <span class="dv">2</span></span>
668<span id="cb132-3"><a href="#cb132-3"></a> <span class="kw">where</span></span>
669<span id="cb132-4"><a href="#cb132-4"></a> mult&#39; n m <span class="ot">=</span></span>
670<span id="cb132-5"><a href="#cb132-5"></a> <span class="kw">if</span> n <span class="op">&lt;=</span> m</span>
671<span id="cb132-6"><a href="#cb132-6"></a> <span class="kw">then</span> empty</span>
672<span id="cb132-7"><a href="#cb132-7"></a> <span class="kw">else</span></span>
673<span id="cb132-8"><a href="#cb132-8"></a> <span class="kw">if</span> n <span class="ot">`mod`</span> m <span class="op">==</span> <span class="dv">0</span></span>
674<span id="cb132-9"><a href="#cb132-9"></a> <span class="kw">then</span> <span class="fu">pure</span> m <span class="op">&lt;|&gt;</span> mult (n <span class="ot">`div`</span> m)</span>
675<span id="cb132-10"><a href="#cb132-10"></a> <span class="kw">else</span> mult&#39; n (m <span class="op">+</span> <span class="dv">1</span>)</span></code></pre></div>
676</section>
677<section class="slide level1">
679<div class="sourceCode" id="cb133"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb133-1"><a href="#cb133-1"></a>mult <span class="dv">10</span><span class="ot"> ::</span> [<span class="dt">Int</span>]</span>
680<span id="cb133-2"><a href="#cb133-2"></a><span class="co">-- [2, 5]</span></span></code></pre></div>
681<div class="sourceCode" id="cb134"><pre class="sourceCode haskell fragment"><code class="sourceCode haskell"><span id="cb134-1"><a href="#cb134-1"></a>mult <span class="dv">10</span><span class="ot"> ::</span> <span class="dt">Maybe</span> <span class="dt">Int</span></span>
682<span id="cb134-2"><a href="#cb134-2"></a><span class="co">-- Just 2</span></span></code></pre></div>
683<div class="sourceCode" id="cb135"><pre class="sourceCode haskell fragment"><code class="sourceCode haskell"><span id="cb135-1"><a href="#cb135-1"></a>mult <span class="dv">23</span><span class="ot"> ::</span> [<span class="dt">Int</span>]</span>
684<span id="cb135-2"><a href="#cb135-2"></a><span class="co">-- []</span></span></code></pre></div>
685<div class="sourceCode" id="cb136"><pre class="sourceCode haskell fragment"><code class="sourceCode haskell"><span id="cb136-1"><a href="#cb136-1"></a>mult <span class="dv">23</span><span class="ot"> ::</span> <span class="dt">Maybe</span> <span class="dt">Int</span></span>
686<span id="cb136-2"><a href="#cb136-2"></a><span class="co">-- Nothing</span></span></code></pre></div>
687</section>
688<section class="slide level1">
690<div class="sourceCode" id="cb137"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb137-1"><a href="#cb137-1"></a><span class="kw">import</span> <span class="dt">Control.Applicative</span></span></code></pre></div>
691</section>
692 </div>
693 </div>
695 <script src="reveal.js/js/reveal.js"></script>
697 <script>
699 // Full list of configuration options available at:
700 // https://github.com/hakimel/reveal.js#configuration
701 Reveal.initialize({
702 // Push each slide change to the browser history
703 history: true,
705 // Optional reveal.js plugins
706 dependencies: [
707 { src: 'reveal.js/lib/js/classList.js', condition: function() { return !document.body.classList; } },
708 { src: 'reveal.js/plugin/zoom-js/zoom.js', async: true },
709 { src: 'reveal.js/plugin/notes/notes.js', async: true }
710 ]
711 });
712 </script>
713 </body>
714</html>