sc-lectures/2.html
2020-04-01 23:35:09 +03:00

715 lines
84 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="generator" content="pandoc">
<meta name="author" content="Ilya Kostyuchenko">
<title>2</title>
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, minimal-ui">
<link rel="stylesheet" href="reveal.js/css/reset.css">
<link rel="stylesheet" href="reveal.js/css/reveal.css">
<style>
code{white-space: pre-wrap;}
span.smallcaps{font-variant: small-caps;}
span.underline{text-decoration: underline;}
div.column{display: inline-block; vertical-align: top; width: 50%;}
div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;}
ul.task-list{list-style: none;}
pre > code.sourceCode { white-space: pre; position: relative; }
pre > code.sourceCode > span { display: inline-block; line-height: 1.25; }
pre > code.sourceCode > span:empty { height: 1.2em; }
code.sourceCode > span { color: inherit; text-decoration: inherit; }
div.sourceCode { margin: 1em 0; }
pre.sourceCode { margin: 0; }
@media screen {
div.sourceCode { overflow: auto; }
}
@media print {
pre > code.sourceCode { white-space: pre-wrap; }
pre > code.sourceCode > span { text-indent: -5em; padding-left: 5em; }
}
pre.numberSource code
{ counter-reset: source-line 0; }
pre.numberSource code > span
{ position: relative; left: -4em; counter-increment: source-line; }
pre.numberSource code > span > a:first-child::before
{ content: counter(source-line);
position: relative; left: -1em; text-align: right; vertical-align: baseline;
border: none; display: inline-block;
-webkit-touch-callout: none; -webkit-user-select: none;
-khtml-user-select: none; -moz-user-select: none;
-ms-user-select: none; user-select: none;
padding: 0 4px; width: 4em;
background-color: #232629;
color: #7a7c7d;
}
pre.numberSource { margin-left: 3em; border-left: 1px solid #7a7c7d; padding-left: 4px; }
div.sourceCode
{ color: #ffffff; background-color: #000000; }
@media screen {
pre > code.sourceCode > span > a:first-child::before { text-decoration: underline; }
}
code span. { color: #ffffff; } /* Normal */
code span.al { color: #95da4c; background-color: #4d1f24; font-weight: bold; } /* Alert */
code span.an { color: #86d5a4; } /* Annotation */
code span.at { color: #94cbf0; } /* Attribute */
code span.bn { color: #ffb06a; } /* BaseN */
code span.bu { color: #bdd1d3; } /* BuiltIn */
code span.cf { color: #ffd998; font-weight: bold; } /* ControlFlow */
code span.ch { color: #a4e0ff; } /* Char */
code span.cn { color: #73d9d9; font-weight: bold; } /* Constant */
code span.co { color: #a1a6a8; } /* Comment */
code span.cv { color: #b6c8c9; } /* CommentVar */
code span.do { color: #a43340; } /* Documentation */
code span.dt { color: #7cc0ec; } /* DataType */
code span.dv { color: #f6b77f; } /* DecVal */
code span.er { color: #e9848e; text-decoration: underline; } /* Error */
code span.ex { color: #96d5ff; font-weight: bold; } /* Extension */
code span.fl { color: #fdae67; } /* Float */
code span.fu { color: #d487f4; } /* Function */
code span.im { color: #76e8a6; } /* Import */
code span.in { color: #f6b176; } /* Information */
code span.kw { color: #ebebc9; font-weight: bold; } /* Keyword */
code span.op { color: #ececde; } /* Operator */
code span.ot { color: #86e9b0; } /* Other */
code span.pp { color: #62e298; } /* Preprocessor */
code span.re { color: #83c7f4; background-color: #153042; } /* RegionMarker */
code span.sc { color: #80ccf4; } /* SpecialChar */
code span.ss { color: #ff909b; } /* SpecialString */
code span.st { color: #ff9f9f; } /* String */
code span.va { color: #56d4d4; } /* Variable */
code span.vs { color: #eca2a9; } /* VerbatimString */
code span.wa { color: #eca2a9; } /* Warning */
</style>
<link rel="stylesheet" href="reveal.js/css/theme/superblack.css" id="theme">
<!-- Printing and PDF exports -->
<script>
var link = document.createElement( 'link' );
link.rel = 'stylesheet';
link.type = 'text/css';
link.href = window.location.search.match( /print-pdf/gi ) ? 'reveal.js/css/print/pdf.css' : 'reveal.js/css/print/paper.css';
document.getElementsByTagName( 'head' )[0].appendChild( link );
</script>
<!--[if lt IE 9]>
<script src="reveal.js/lib/js/html5shiv.js"></script>
<![endif]-->
<style>
div.sourceCode {
background-color: transparent;
overflow: auto;
margin: 0em;
}
pre.sourceCode {
margin: 8px auto;
}
</style>
</head>
<body>
<div class="reveal">
<div class="slides">
<section id="функциональное-программирование" class="slide level1">
<h1>Функциональное программирование</h1>
</section>
<section id="структуры" class="slide level1">
<h1>Структуры</h1>
<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>
<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>
<span id="cb1-3"><a href="#cb1-3"></a></span>
<span id="cb1-4"><a href="#cb1-4"></a><span class="kw">data</span> <span class="dt">Shape</span> <span class="ot">=</span></span>
<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>
<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>
<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>
</section>
<section class="slide level1">
<h2 id="структура-человек">Структура “человек”</h2>
<p>Имя, Фамилия, Отчество, Адрес, Почта, Возраст</p>
<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>
<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>
<p><img data-src="images/ohno.png" class="fragment" height="200" /></p>
</section>
<section class="slide level1">
<h2 id="функции">Функции!</h2>
<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>
<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>
<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>
<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>
<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>
<span id="cb6-2"><a href="#cb6-2"></a>setFirstName</span>
<span id="cb6-3"><a href="#cb6-3"></a> newName</span>
<span id="cb6-4"><a href="#cb6-4"></a> (<span class="dt">Person</span> _ lName mName address email age)</span>
<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>
<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>
<span id="cb7-2"><a href="#cb7-2"></a>lastName (<span class="dt">Person</span> _ lName _ _ _ _) <span class="ot">=</span> lName</span>
<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>
<span id="cb7-4"><a href="#cb7-4"></a>setLastName</span>
<span id="cb7-5"><a href="#cb7-5"></a> newLastName</span>
<span id="cb7-6"><a href="#cb7-6"></a> (<span class="dt">Person</span> fName _ mName address email age)</span>
<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>
</section>
<section class="slide level1">
<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>
<span id="cb8-2"><a href="#cb8-2"></a>middleName (<span class="dt">Person</span> _ _ mName _ _ _) <span class="ot">=</span> mName</span>
<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>
<span id="cb8-4"><a href="#cb8-4"></a>setMiddleName</span>
<span id="cb8-5"><a href="#cb8-5"></a> newMiddleName</span>
<span id="cb8-6"><a href="#cb8-6"></a> (<span class="dt">Person</span> fName lName _ address email age)</span>
<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>
<p><img data-src="images/ohno.png" class="fragment" height="200" /></p>
<p><span class="fragment">А что если структуры еще больше?</span></p>
</section>
<section class="slide level1">
<h2 id="record-syntax">Record syntax</h2>
<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>
<span id="cb9-2"><a href="#cb9-2"></a> <span class="ot">=</span> <span class="dt">Person</span></span>
<span id="cb9-3"><a href="#cb9-3"></a> {<span class="ot"> firstName ::</span> <span class="dt">String</span>,</span>
<span id="cb9-4"><a href="#cb9-4"></a><span class="ot"> lastName ::</span> <span class="dt">String</span>,</span>
<span id="cb9-5"><a href="#cb9-5"></a><span class="ot"> middleName ::</span> <span class="dt">String</span>,</span>
<span id="cb9-6"><a href="#cb9-6"></a><span class="ot"> address ::</span> <span class="dt">String</span>,</span>
<span id="cb9-7"><a href="#cb9-7"></a><span class="ot"> email ::</span> <span class="dt">String</span>,</span>
<span id="cb9-8"><a href="#cb9-8"></a><span class="ot"> age ::</span> <span class="dt">Natural</span></span>
<span id="cb9-9"><a href="#cb9-9"></a> }</span></code></pre></div>
<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>
<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>
<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>
<span id="cb10-4"><a href="#cb10-4"></a><span class="co">-- ...</span></span></code></pre></div>
<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>
<span id="cb11-2"><a href="#cb11-2"></a>setFirstName newName person <span class="ot">=</span> person {firstName <span class="ot">=</span> newName}</span>
<span id="cb11-3"><a href="#cb11-3"></a><span class="co">-- Делает копию, заменяя одно (или нескеолько) поле.</span></span>
<span id="cb11-4"><a href="#cb11-4"></a><span class="co">-- (То есть функции set... не нужны)</span></span></code></pre></div>
</section>
<section id="абстракция" class="slide level1">
<h1>Абстракция</h1>
</section>
<section class="slide level1">
<blockquote>
<p>Полиморфизм одну реализацию можно применять к разным типам.</p>
</blockquote>
</section>
<section class="slide level1">
<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>
<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>
<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>
<p><span class="fragment">Problem: сама функция с <code>a</code> и <code>b</code> делать ничего не может она про них ничего не знает.</span></p>
</section>
<section class="slide level1">
<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>
<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>
<p><span class="fragment">Откуда <code>sort</code> узнает что такое <code>a</code> и как их сравнивать?</span></p>
</section>
<section class="slide level1">
<h2 id="typeclass">Typeclass</h2>
</section>
<section class="slide level1">
<p>Самое близкое интрефейс.</p>
<blockquote>
<p>Описывает свойства, которыми должен обладать объект</p>
</blockquote>
</section>
<section class="slide level1">
<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>
<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>
<p><span class="fragment"><code>a</code> относится к классу <code>Eq</code> если существует такая функция <code>(==) :: a -&gt; a -&gt; Bool</code></span></p>
</section>
<section class="slide level1">
<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>
<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>
<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>
<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>
<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>
<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>
<p><span class="fragment">instance “удовлетворяет”, а не “экземпляр”.</span></p>
</section>
<section class="slide level1">
<h2 id="использование">Использование</h2>
<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>
<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>
<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>
</section>
<section class="slide level1">
<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>
<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>
<p><span class="fragment"><code>a</code> относится к классу <code>Ord</code> если он относится к классу <code>Ord</code> и существует такая функция <code>(&lt;=) :: a -&gt; a -&gt; Bool</code></span></p>
</section>
<section class="slide level1">
<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>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
</section>
<section class="slide level1">
<h2 id="использование-1">Использование</h2>
<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>
<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>
<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>
<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>
<p><span class="fragment">Тут мы можем использовать <code>&gt;</code> на типах <code>a</code> потому что внутри функции уже есть определение <code>Ord a</code>.</span></p>
</section>
<section class="slide level1">
<p><code>notEqual</code> в стандартной библиотеке определен как <code>/=</code>.</p>
</section>
<section class="slide level1">
<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>
<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>
<p><span class="fragment">Из-за сильной системы типов гарантируется что функция вернет один из своих аргументов.</span></p>
</section>
<section class="slide level1">
<h2 id="case">Case</h2>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
<p><span class="fragment">Просто возможность делать pattern matching где угодно, а не только в аргументах функций.</span></p>
</section>
<section class="slide level1">
<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>
<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>
<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>
<span id="cb37-2"><a href="#cb37-2"></a><span class="fu">maximum</span> [] <span class="ot">=</span> <span class="dt">Nothing</span></span>
<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>
<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>
<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>
</section>
<section class="slide level1">
<h2 id="полиморфные-инстансы">Полиморфные инстансы</h2>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
<span id="cb41-2"><a href="#cb41-2"></a> <span class="co">-- Потому что мы хотим чтобы Nothing был меньше всех</span></span>
<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>
<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>
<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>
</section>
<section class="slide level1">
<p>Что нам это дает?</p>
<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>
<span id="cb42-2"><a href="#cb42-2"></a><span class="fu">maximum</span> [] <span class="ot">=</span> <span class="dt">Nothing</span></span>
<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>
<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>
<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>
<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>
<span id="cb43-2"><a href="#cb43-2"></a><span class="fu">maximum</span> [] <span class="ot">=</span> <span class="dt">Nothing</span></span>
<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>
</section>
<section class="slide level1">
<h2 id="моноид">Моноид</h2>
<blockquote>
<p>Моноид полугруппа с нейтральным элементом</p>
</blockquote>
</section>
<section class="slide level1">
<h2 id="полугруппа">Полугруппа</h2>
<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>
<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>
<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>
<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>
<h2 id="моноид-1"><span class="fragment">Моноид</span></h2>
<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>
<span id="cb46-2"><a href="#cb46-2"></a><span class="ot"> mempty ::</span> s</span></code></pre></div>
<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>
<span id="cb47-2"><a href="#cb47-2"></a> <span class="fu">mempty</span> <span class="ot">=</span> []</span></code></pre></div>
</section>
<section class="slide level1">
<p>“Схлопывает” список моноидов.</p>
<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>
<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>
<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>
<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>
<span id="cb50-2"><a href="#cb50-2"></a><span class="co">-- [1, 3, 5, 42, 69]</span></span></code></pre></div>
</section>
<section class="slide level1">
<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>
<span id="cb51-2"><a href="#cb51-2"></a>fold [] <span class="ot">=</span> <span class="fu">mempty</span></span>
<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>
<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>
<span id="cb52-2"><a href="#cb52-2"></a><span class="co">-- Что должно произойти?</span></span></code></pre></div>
</section>
<section class="slide level1">
<p>У целых чисел нет одного определения моноида.</p>
<p><span class="fragment">Но мы можем определить свои типы!</span></p>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
<span id="cb57-2"><a href="#cb57-2"></a><span class="co">-- [2, 3, 4]</span></span></code></pre></div>
<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>
<span id="cb58-2"><a href="#cb58-2"></a><span class="co">-- 6</span></span></code></pre></div>
</section>
<section id="deriving" class="slide level1">
<h1>Deriving</h1>
<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>
<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>
<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>
<span id="cb60-2"><a href="#cb60-2"></a> <span class="kw">deriving</span> <span class="dt">Show</span></span></code></pre></div>
<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>
<span id="cb61-2"><a href="#cb61-2"></a><span class="co">-- Bar 1 2 &quot;hello&quot;</span></span></code></pre></div>
<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>
<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>
<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>
<span id="cb63-2"><a href="#cb63-2"></a><span class="co">-- True</span></span>
<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>
<span id="cb63-4"><a href="#cb63-4"></a><span class="co">-- False</span></span></code></pre></div>
<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>
<span id="cb64-2"><a href="#cb64-2"></a><span class="co">-- True</span></span></code></pre></div>
</section>
<section class="slide level1">
<h2 id="синонимы-типов">Синонимы типов</h2>
<p><span class="fragment">Тип можно обозвать как-то по-другому чтобы код было удобнее читать.</span></p>
<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>
<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>
<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>
<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>
<p><span class="fragment">Буквально эквивалентно тому чтобы сделать find and replace по коду.</span></p>
</section>
<section class="slide level1">
<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>
<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>
<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>
<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>
<span id="cb70-2"><a href="#cb70-2"></a>name <span class="ot">=</span> <span class="st">&quot;Vasya&quot;</span></span>
<span id="cb70-3"><a href="#cb70-3"></a></span>
<span id="cb70-4"><a href="#cb70-4"></a><span class="co">-- This is fine.</span></span>
<span id="cb70-5"><a href="#cb70-5"></a>scream name</span>
<span id="cb70-6"><a href="#cb70-6"></a><span class="co">-- &quot;VASYA&quot;</span></span></code></pre></div>
<p><span class="fragment">В функцию <code>capitalize</code> можно передать константу типа <code>Name</code> потому что <code>String</code> и <code>Name</code> это одно и то же.</span></p>
</section>
<section class="slide level1">
<p><code>data</code> новый тип</p>
<p><code>type</code> просто обозвали по-другому</p>
</section>
<section class="slide level1">
<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>
<span id="cb71-2"><a href="#cb71-2"></a>fold [] <span class="ot">=</span> <span class="fu">mempty</span></span>
<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>
<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>
<span id="cb72-2"><a href="#cb72-2"></a><span class="co">-- &quot;HelloWorld&quot;</span></span>
<span id="cb72-3"><a href="#cb72-3"></a><span class="co">--</span></span>
<span id="cb72-4"><a href="#cb72-4"></a><span class="co">-- Потому что</span></span>
<span id="cb72-5"><a href="#cb72-5"></a><span class="co">-- type String = [Char]</span></span></code></pre></div>
</section>
<section id="обработка-ошибок" class="slide level1">
<h1>Обработка ошибок</h1>
</section>
<section class="slide level1">
<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>
<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>
<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>
<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>
<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>
<span id="cb74-2"><a href="#cb74-2"></a><span class="co">// 1</span></span></code></pre></div>
<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>
<span id="cb75-2"><a href="#cb75-2"></a><span class="co">// null</span></span></code></pre></div>
<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>
<span id="cb76-2"><a href="#cb76-2"></a> V <span class="fu">get</span>(K key) {</span>
<span id="cb76-3"><a href="#cb76-3"></a> ...</span></code></pre></div>
<p><span class="fragment">Неявный контекст ошибки ВЕЗДЕ.</span></p>
</section>
<section class="slide level1">
<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>
<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>
<span id="cb77-3"><a href="#cb77-3"></a> ...</span></code></pre></div>
<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>
<span id="cb78-2"><a href="#cb78-2"></a></span>
<span id="cb78-3"><a href="#cb78-3"></a><span class="kw">if</span> (result.<span class="fu">second</span>()) {</span>
<span id="cb78-4"><a href="#cb78-4"></a> <span class="fu">print</span>(m.<span class="fu">first</span>());</span>
<span id="cb78-5"><a href="#cb78-5"></a>} <span class="kw">else</span> {</span>
<span id="cb78-6"><a href="#cb78-6"></a> <span class="fu">print</span>(<span class="st">&quot;oh no&quot;</span>);</span>
<span id="cb78-7"><a href="#cb78-7"></a>}</span>
<span id="cb78-8"><a href="#cb78-8"></a><span class="co">// 1</span></span></code></pre></div>
<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>
<span id="cb79-2"><a href="#cb79-2"></a></span>
<span id="cb79-3"><a href="#cb79-3"></a><span class="kw">if</span> (result.<span class="fu">second</span>()) {</span>
<span id="cb79-4"><a href="#cb79-4"></a> <span class="fu">print</span>(m.<span class="fu">first</span>());</span>
<span id="cb79-5"><a href="#cb79-5"></a>} <span class="kw">else</span> {</span>
<span id="cb79-6"><a href="#cb79-6"></a> <span class="fu">print</span>(<span class="st">&quot;oh no&quot;</span>);</span>
<span id="cb79-7"><a href="#cb79-7"></a>}</span>
<span id="cb79-8"><a href="#cb79-8"></a><span class="co">// oh no</span></span></code></pre></div>
</section>
<section class="slide level1">
<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>
<span id="cb80-2"><a href="#cb80-2"></a> V <span class="fu">get</span>(K key) <span class="kw">throws</span> NoElementException {</span>
<span id="cb80-3"><a href="#cb80-3"></a> ...</span></code></pre></div>
<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>
<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>
<span id="cb81-3"><a href="#cb81-3"></a>} <span class="kw">catch</span> (NoElementException e) {</span>
<span id="cb81-4"><a href="#cb81-4"></a> <span class="fu">print</span>(<span class="st">&quot;oh no&quot;</span>);</span>
<span id="cb81-5"><a href="#cb81-5"></a>}</span>
<span id="cb81-6"><a href="#cb81-6"></a><span class="co">// oh no</span></span></code></pre></div>
</section>
<section class="slide level1">
<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>
<span id="cb82-2"><a href="#cb82-2"></a> ...</span></code></pre></div>
<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>
<span id="cb83-2"><a href="#cb83-2"></a> Optional&lt;V&gt; <span class="fu">get</span>(K key) {</span>
<span id="cb83-3"><a href="#cb83-3"></a> ...</span></code></pre></div>
</section>
<section class="slide level1">
<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>
<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>
<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>
<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>
<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>
<span id="cb87-2"><a href="#cb87-2"></a><span class="co">-- Just 1</span></span></code></pre></div>
<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>
<span id="cb88-2"><a href="#cb88-2"></a><span class="co">-- Nothing</span></span></code></pre></div>
<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>
<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>
<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>
</section>
<section class="slide level1">
<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>
<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>
<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>
<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>
<span id="cb93-2"><a href="#cb93-2"></a> <span class="kw">if</span> balance card <span class="op">&gt;=</span> amount</span>
<span id="cb93-3"><a href="#cb93-3"></a> <span class="kw">then</span> <span class="dt">Right</span> (withdraw amount card)</span>
<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>
</section>
<section class="slide level1">
<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>
<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>
<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>
<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>
<span id="cb96-2"><a href="#cb96-2"></a></span>
<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>
<span id="cb96-4"><a href="#cb96-4"></a>newAcccount <span class="ot">=</span></span>
<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>
<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>
<span id="cb97-2"><a href="#cb97-2"></a> updateAccount account (makePayment card (<span class="dt">RUB</span> <span class="dv">150</span>))</span>
<span id="cb97-3"><a href="#cb97-3"></a><span class="co">-- (Card -&gt; Account) (Either PaymentError Card)</span></span></code></pre></div>
<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>
<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>
<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>
<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>
</section>
<section class="slide level1">
<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>
<span id="cb99-2"><a href="#cb99-2"></a> updateAccount account (makePayment card (<span class="dt">RUB</span> <span class="dv">150</span>))</span>
<span id="cb99-3"><a href="#cb99-3"></a><span class="co">-- (Card -&gt; Account) (Either PaymentError Card)</span></span></code></pre></div>
<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>
<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>
<span id="cb100-3"><a href="#cb100-3"></a><span class="co">-- | (Card -&gt; Account) (Either PaymentError Card)</span></span>
<span id="cb100-4"><a href="#cb100-4"></a><span class="co">-- |</span></span>
<span id="cb100-5"><a href="#cb100-5"></a><span class="co">-- (Card -&gt; Account)</span></span>
<span id="cb100-6"><a href="#cb100-6"></a><span class="co">-- -&gt; (Either PaymentError Card</span></span>
<span id="cb100-7"><a href="#cb100-7"></a><span class="co">-- -&gt; Either PaymentError Account)</span></span></code></pre></div>
</section>
<section class="slide level1">
<h2 id="lists">Lists!</h2>
<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>
<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>
<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>
<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>
<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>
<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>
<span id="cb103-5"><a href="#cb103-5"></a> )</span></code></pre></div>
<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>
<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>
</section>
<section class="slide level1">
<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>
<p><span class="fragment">А мы можем обобщить <code>F</code>?</span></p>
<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>
<span id="cb107-2"><a href="#cb107-2"></a> <span class="dt">Functor</span> f <span class="ot">=&gt;</span></span>
<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>
<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>
</section>
<section id="functor" class="slide level1">
<h1>Functor!</h1>
<p><img data-src="images/fmap1.png" class="fragment" width="450" /></p>
<p><img data-src="images/fmap2.png" class="fragment" width="450" /></p>
</section>
<section class="slide level1">
<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>
<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>
<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>
<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>
<span id="cb109-3"><a href="#cb109-3"></a> <span class="fu">fmap</span> _ [] <span class="ot">=</span> []</span>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
</section>
<section class="slide level1">
<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>
<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>
<span id="cb112-3"><a href="#cb112-3"></a></span>
<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>
<span id="cb112-5"><a href="#cb112-5"></a>newAcccount <span class="ot">=</span></span>
<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>
</section>
<section class="slide level1">
<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>
<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>
<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>
<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>
<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>
<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>
<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>
</section>
<section class="slide level1">
<h2 id="functor-monoid">Functor + Monoid</h2>
<h2 id="alternative"><span class="fragment">= Alternative!</span></h2>
<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>
<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>
<span id="cb117-3"><a href="#cb117-3"></a><span class="ot"> mempty ::</span> s</span></code></pre></div>
<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>
<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>
<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>
<span id="cb119-3"><a href="#cb119-3"></a><span class="ot"> empty ::</span> f a</span></code></pre></div>
</section>
<section class="slide level1">
<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>
<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>
<span id="cb120-3"><a href="#cb120-3"></a><span class="ot"> empty ::</span> f a</span></code></pre></div>
<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>
<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>
<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>
<span id="cb121-4"><a href="#cb121-4"></a></span>
<span id="cb121-5"><a href="#cb121-5"></a> empty <span class="ot">=</span> <span class="dt">Nothing</span></span></code></pre></div>
<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>
<span id="cb122-2"><a href="#cb122-2"></a><span class="co">-- Just 42</span></span></code></pre></div>
<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>
<span id="cb123-2"><a href="#cb123-2"></a><span class="co">-- Just 69</span></span></code></pre></div>
</section>
<section class="slide level1">
<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>
<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>
<span id="cb124-3"><a href="#cb124-3"></a> _ <span class="op">&lt;|&gt;</span> y <span class="ot">=</span> y</span>
<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>
<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>
<span id="cb125-2"><a href="#cb125-2"></a><span class="co">-- Right 8</span></span></code></pre></div>
<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>
<span id="cb126-2"><a href="#cb126-2"></a><span class="co">-- Right 42</span></span></code></pre></div>
<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>
<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>
</section>
<section class="slide level1">
<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>
<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>
<span id="cb129-3"><a href="#cb129-3"></a> empty <span class="ot">=</span> []</span></code></pre></div>
<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>
<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>
<span id="cb131-2"><a href="#cb131-2"></a><span class="ot"> pure ::</span> a <span class="ot">-&gt;</span> f a</span>
<span id="cb131-3"><a href="#cb131-3"></a> <span class="op">...</span></span></code></pre></div>
<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>
<span id="cb132-2"><a href="#cb132-2"></a>mult n <span class="ot">=</span> mult&#39; n <span class="dv">2</span></span>
<span id="cb132-3"><a href="#cb132-3"></a> <span class="kw">where</span></span>
<span id="cb132-4"><a href="#cb132-4"></a> mult&#39; n m <span class="ot">=</span></span>
<span id="cb132-5"><a href="#cb132-5"></a> <span class="kw">if</span> n <span class="op">&lt;=</span> m</span>
<span id="cb132-6"><a href="#cb132-6"></a> <span class="kw">then</span> empty</span>
<span id="cb132-7"><a href="#cb132-7"></a> <span class="kw">else</span></span>
<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>
<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>
<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>
</section>
<section class="slide level1">
<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>
<span id="cb133-2"><a href="#cb133-2"></a><span class="co">-- [2, 5]</span></span></code></pre></div>
<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>
<span id="cb134-2"><a href="#cb134-2"></a><span class="co">-- Just 2</span></span></code></pre></div>
<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>
<span id="cb135-2"><a href="#cb135-2"></a><span class="co">-- []</span></span></code></pre></div>
<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>
<span id="cb136-2"><a href="#cb136-2"></a><span class="co">-- Nothing</span></span></code></pre></div>
</section>
<section class="slide level1">
<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>
</section>
</div>
</div>
<script src="reveal.js/js/reveal.js"></script>
<script>
// Full list of configuration options available at:
// https://github.com/hakimel/reveal.js#configuration
Reveal.initialize({
// Push each slide change to the browser history
history: true,
// Optional reveal.js plugins
dependencies: [
{ src: 'reveal.js/lib/js/classList.js', condition: function() { return !document.body.classList; } },
{ src: 'reveal.js/plugin/zoom-js/zoom.js', async: true },
{ src: 'reveal.js/plugin/notes/notes.js', async: true }
]
});
</script>
</body>
</html>