git.iko.soy/ikoHSE/sc-lectures
on master help sign in
Update 🥳
commit8a0a9fe47a72506401e6da16853b673d0515ae59 authoriko <ilyakooo0@gmail.com> dateMon 18 May 2020, 00:03 (6 years ago) parent29262f6
2 files changed+220−180
3.html+164−148 3.md+56−32
3.html+164−148
@@ -277,7 +277,7 @@
277277<div class="sourceCode" id="cb33"><pre class="sourceCode haskell fragment"><code class="sourceCode haskell"><span id="cb33-1"><a href="#cb33-1"></a><span class="kw">instance</span> <span class="dt">Monad</span> <span class="dt">WithLog</span> <span class="kw">where</span></span>
278278<span id="cb33-2"><a href="#cb33-2"></a> (<span class="op">&lt;=&lt;</span>) f g x <span class="ot">=</span> <span class="dt">WithLog</span> x3 (log1 <span class="op">&lt;&gt;</span> log2)</span>
279279<span id="cb33-3"><a href="#cb33-3"></a> <span class="kw">where</span></span>
280−<span id="cb33-4"><a href="#cb33-4"></a> (<span class="dt">WithLog</span> x2 log1) <span class="ot">=</span> g x1</span>
280+<span id="cb33-4"><a href="#cb33-4"></a> (<span class="dt">WithLog</span> x2 log1) <span class="ot">=</span> g x</span>
281281<span id="cb33-5"><a href="#cb33-5"></a> (<span class="dt">WithLog</span> x3 log2) <span class="ot">=</span> f x2</span></code></pre></div>
282282</section>
283283<section class="slide level2">
@@ -304,8 +304,8 @@
304304<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="ot">(&gt;&gt;=) ::</span> <span class="dt">Monad</span> m <span class="ot">=&gt;</span> m b <span class="ot">-&gt;</span> (b <span class="ot">-&gt;</span> m c) <span class="ot">-&gt;</span> m c</span></code></pre></div>
305305<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="ot">buyCoffee ::</span> <span class="dt">Order</span> <span class="ot">-&gt;</span> <span class="dt">Maybe</span> <span class="dt">Payment</span></span>
306306<span id="cb41-2"><a href="#cb41-2"></a>buyCoffee order <span class="ot">=</span> getCoffee order <span class="op">&gt;&gt;=</span> payForCoffee</span></code></pre></div>
307−<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="ot">maybeBuyCoffee ::</span> <span class="dt">Myabe</span> <span class="dt">Order</span> <span class="ot">-&gt;</span> <span class="dt">Maybe</span> <span class="dt">Payment</span></span>
308−<span id="cb42-2"><a href="#cb42-2"></a>maybeBuyCoffee order <span class="ot">=</span> order <span class="op">&gt;&gt;=</span> buyCoffee</span></code></pre></div>
307+<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="ot">maybeBuyCoffee ::</span> <span class="dt">Maybe</span> <span class="dt">Order</span> <span class="ot">-&gt;</span> <span class="dt">Maybe</span> <span class="dt">Payment</span></span>
308+<span id="cb42-2"><a href="#cb42-2"></a>maybeBuyCoffee mOrder <span class="ot">=</span> mOrder <span class="op">&gt;&gt;=</span> buyCoffee</span></code></pre></div>
309309<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="ot">(&gt;&gt;=) ::</span> <span class="dt">Monad</span> m <span class="ot">=&gt;</span> m b <span class="ot">-&gt;</span> (b <span class="ot">-&gt;</span> m c) <span class="ot">-&gt;</span> m c</span></code></pre></div>
310310<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="ot">(&gt;=&gt;) ::</span> <span class="dt">Monad</span> m <span class="ot">=&gt;</span> (a <span class="ot">-&gt;</span> m b) <span class="ot">-&gt;</span> (b <span class="ot">-&gt;</span> m c) <span class="ot">-&gt;</span> (a <span class="ot">-&gt;</span> m c)</span></code></pre></div>
311311<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="ot">-&gt;</span> m b) <span class="ot">-&gt;</span> (b <span class="ot">-&gt;</span> m c) <span class="ot">-&gt;</span> (() <span class="ot">-&gt;</span> m c)</span></code></pre></div>
@@ -315,13 +315,13 @@
315315
316316<div class="sourceCode" id="cb47"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb47-1"><a href="#cb47-1"></a><span class="ot">(&gt;=&gt;) ::</span> <span class="dt">Monad</span> m <span class="ot">=&gt;</span> (a <span class="ot">-&gt;</span> m b) <span class="ot">-&gt;</span> (b <span class="ot">-&gt;</span> m c) <span class="ot">-&gt;</span> (a <span class="ot">-&gt;</span> m c)</span></code></pre></div>
317317<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">(&gt;&gt;=) ::</span> <span class="dt">Monad</span> m <span class="ot">=&gt;</span> m b <span class="ot">-&gt;</span> (b <span class="ot">-&gt;</span> m c) <span class="ot">-&gt;</span> m c</span>
318−<span id="cb48-2"><a href="#cb48-2"></a>(<span class="op">&gt;&gt;=</span>) mb f <span class="ot">=</span> ( (\() <span class="ot">-&gt;</span> mb) <span class="op">&gt;=&gt;</span> f ) ()</span></code></pre></div>
319−<div class="sourceCode" id="cb49"><pre class="sourceCode haskell fragment"><code class="sourceCode haskell"><span id="cb49-1"><a href="#cb49-1"></a>(<span class="op">&gt;&gt;=</span>) mb f <span class="ot">=</span> ( (\() <span class="ot">-&gt;</span> mb) <span class="op">&gt;=&gt;</span> f ) ()</span>
320−<span id="cb49-2"><a href="#cb49-2"></a><span class="co">-- () -&gt; m b |</span></span>
321−<span id="cb49-3"><a href="#cb49-3"></a><span class="co">-- b -&gt; m c</span></span>
318+<span id="cb48-2"><a href="#cb48-2"></a>(<span class="op">&gt;&gt;=</span>) mb bmc <span class="ot">=</span> ( (\() <span class="ot">-&gt;</span> mb) <span class="op">&gt;=&gt;</span> bmc ) ()</span></code></pre></div>
319+<div class="sourceCode" id="cb49"><pre class="sourceCode haskell fragment"><code class="sourceCode haskell"><span id="cb49-1"><a href="#cb49-1"></a>(<span class="op">&gt;&gt;=</span>) mb bmc <span class="ot">=</span> ( (\() <span class="ot">-&gt;</span> mb) <span class="op">&gt;=&gt;</span> bmc ) ()</span>
320+<span id="cb49-2"><a href="#cb49-2"></a><span class="co">-- () -&gt; m b |</span></span>
321+<span id="cb49-3"><a href="#cb49-3"></a><span class="co">-- b -&gt; m c</span></span>
322322<span id="cb49-4"><a href="#cb49-4"></a><span class="co">--</span></span>
323−<span id="cb49-5"><a href="#cb49-5"></a><span class="co">-- ^-------------------^</span></span>
324−<span id="cb49-6"><a href="#cb49-6"></a><span class="co">-- () -&gt; m c</span></span></code></pre></div>
323+<span id="cb49-5"><a href="#cb49-5"></a><span class="co">-- ^-----------------------^</span></span>
324+<span id="cb49-6"><a href="#cb49-6"></a><span class="co">-- () -&gt; m c</span></span></code></pre></div>
325325</section>
326326<section class="slide level2">
327327
@@ -375,24 +375,22 @@
375375<span id="cb58-2"><a href="#cb58-2"></a> {<span class="ot"> runReader ::</span> r <span class="ot">-&gt;</span> a</span>
376376<span id="cb58-3"><a href="#cb58-3"></a> }</span></code></pre></div>
377377<p><span class="fragment"><code>r</code> – то, что у нас в “окружении”.</span></p>
378−<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="ot">getCoffee ::</span> <span class="dt">Order</span> <span class="ot">-&gt;</span> <span class="dt">Reader</span> <span class="dt">Markup</span> <span class="dt">Coffee</span></span>
379−<span id="cb59-2"><a href="#cb59-2"></a><span class="ot">payForCoffee ::</span> <span class="dt">Coffee</span> <span class="ot">-&gt;</span> <span class="dt">Reader</span> <span class="dt">Markup</span> <span class="dt">Payment</span></span></code></pre></div>
380−<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="ot">payment ::</span> <span class="dt">Payment</span></span>
381−<span id="cb60-2"><a href="#cb60-2"></a>payment <span class="ot">=</span> runReader (payForCoffee coffee) markup</span></code></pre></div>
382378</section>
383379<section class="slide level2">
384380
385−<div class="sourceCode" id="cb61"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb61-1"><a href="#cb61-1"></a><span class="kw">data</span> <span class="dt">Reader</span> r a <span class="ot">=</span> <span class="dt">Reader</span> {<span class="ot"> runReader ::</span> r <span class="ot">-&gt;</span> a }</span>
386−<span id="cb61-2"><a href="#cb61-2"></a></span>
387−<span id="cb61-3"><a href="#cb61-3"></a><span class="ot">getCoffee ::</span> <span class="dt">Order</span> <span class="ot">-&gt;</span> <span class="dt">Reader</span> <span class="dt">Markup</span> <span class="dt">Coffee</span></span>
388−<span id="cb61-4"><a href="#cb61-4"></a><span class="ot">payForCoffee ::</span> <span class="dt">Coffee</span> <span class="ot">-&gt;</span> <span class="dt">Reader</span> <span class="dt">Markup</span> <span class="dt">Payment</span></span></code></pre></div>
389−<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="ot">buyCoffee ::</span> <span class="dt">Order</span> <span class="ot">-&gt;</span> <span class="dt">Reader</span> <span class="dt">Markup</span> <span class="dt">Payment</span></span>
390−<span id="cb62-2"><a href="#cb62-2"></a>buyCoffee <span class="ot">=</span> payForCoffee <span class="op">&lt;=&lt;</span> getCoffee</span></code></pre></div>
391−<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="kw">type</span> <span class="dt">PricingEnv</span> <span class="ot">=</span> <span class="dt">Reader</span> <span class="dt">Markup</span></span></code></pre></div>
392−<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="ot">getCoffee ::</span> <span class="dt">Order</span> <span class="ot">-&gt;</span> <span class="dt">PricingEnv</span> <span class="dt">Coffee</span></span>
393−<span id="cb64-2"><a href="#cb64-2"></a><span class="ot">payForCoffee ::</span> <span class="dt">Coffee</span> <span class="ot">-&gt;</span> <span class="dt">PricingEnv</span> <span class="dt">Payment</span></span>
394−<span id="cb64-3"><a href="#cb64-3"></a><span class="ot">buyCoffee ::</span> <span class="dt">Order</span> <span class="ot">-&gt;</span> <span class="dt">PricingEnv</span> <span class="dt">Payment</span></span>
395−<span id="cb64-4"><a href="#cb64-4"></a>buyCoffee <span class="ot">=</span> payForCoffee <span class="op">&lt;=&lt;</span> getCoffee</span></code></pre></div>
381+<div class="sourceCode" id="cb59"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb59-1"><a href="#cb59-1"></a><span class="kw">data</span> <span class="dt">Reader</span> r a <span class="ot">=</span> <span class="dt">Reader</span> {<span class="ot"> runReader ::</span> r <span class="ot">-&gt;</span> a }</span>
382+<span id="cb59-2"><a href="#cb59-2"></a></span>
383+<span id="cb59-3"><a href="#cb59-3"></a><span class="ot">getCoffee ::</span> <span class="dt">Order</span> <span class="ot">-&gt;</span> <span class="dt">Markup</span> <span class="ot">-&gt;</span> <span class="dt">Coffee</span></span>
384+<span id="cb59-4"><a href="#cb59-4"></a><span class="ot">payForCoffee ::</span> <span class="dt">Coffee</span> <span class="ot">-&gt;</span> <span class="dt">Markup</span> <span class="ot">-&gt;</span> <span class="dt">Payment</span></span></code></pre></div>
385+<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="ot">getCoffee ::</span> <span class="dt">Order</span> <span class="ot">-&gt;</span> <span class="dt">Reader</span> <span class="dt">Markup</span> <span class="dt">Coffee</span></span>
386+<span id="cb60-2"><a href="#cb60-2"></a><span class="ot">payForCoffee ::</span> <span class="dt">Coffee</span> <span class="ot">-&gt;</span> <span class="dt">Reader</span> <span class="dt">Markup</span> <span class="dt">Payment</span></span></code></pre></div>
387+<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="kw">type</span> <span class="dt">PricingEnv</span> <span class="ot">=</span> <span class="dt">Reader</span> <span class="dt">Markup</span></span></code></pre></div>
388+<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="ot">getCoffee ::</span> <span class="dt">Order</span> <span class="ot">-&gt;</span> <span class="dt">PricingEnv</span> <span class="dt">Coffee</span></span>
389+<span id="cb62-2"><a href="#cb62-2"></a><span class="ot">payForCoffee ::</span> <span class="dt">Coffee</span> <span class="ot">-&gt;</span> <span class="dt">PricingEnv</span> <span class="dt">Payment</span></span></code></pre></div>
390+<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="ot">buyCoffee ::</span> <span class="dt">Order</span> <span class="ot">-&gt;</span> <span class="dt">PricingEnv</span> <span class="dt">Payment</span></span>
391+<span id="cb63-2"><a href="#cb63-2"></a>buyCoffee <span class="ot">=</span> payForCoffee <span class="op">&lt;=&lt;</span> getCoffee</span></code></pre></div>
392+<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="ot">payment ::</span> <span class="dt">Payment</span></span>
393+<span id="cb64-2"><a href="#cb64-2"></a>payment <span class="ot">=</span> runReader (buyCoffee order) markup</span></code></pre></div>
396394</section>
397395<section class="slide level2">
398396
@@ -445,83 +443,88 @@
445443<span id="cb69-2"><a href="#cb69-2"></a><span class="ot">qux ::</span> a <span class="ot">-&gt;</span> <span class="dt">Reader</span> r b</span>
446444<span id="cb69-3"><a href="#cb69-3"></a></span>
447445<span id="cb69-4"><a href="#cb69-4"></a><span class="ot">foo ::</span> <span class="dt">Reader</span> r b</span>
448−<span id="cb69-5"><a href="#cb69-5"></a>foo <span class="ot">=</span> bar <span class="op">&gt;&gt;=</span> \a <span class="ot">-&gt;</span> qux a</span></code></pre></div>
446+<span id="cb69-5"><a href="#cb69-5"></a>foo <span class="ot">=</span> bar <span class="op">&gt;&gt;=</span> \x <span class="ot">-&gt;</span> qux x</span></code></pre></div>
449447<div class="sourceCode" id="cb70"><pre class="sourceCode haskell fragment"><code class="sourceCode haskell"><span id="cb70-1"><a href="#cb70-1"></a>foo <span class="ot">=</span> <span class="kw">do</span></span>
450−<span id="cb70-2"><a href="#cb70-2"></a> a <span class="ot">&lt;-</span> bar</span>
451−<span id="cb70-3"><a href="#cb70-3"></a> qux a</span></code></pre></div>
448+<span id="cb70-2"><a href="#cb70-2"></a> <span class="co">-- (x :: a) &lt;- (bar :: Reader r a)</span></span>
449+<span id="cb70-3"><a href="#cb70-3"></a> x <span class="ot">&lt;-</span> bar</span>
450+<span id="cb70-4"><a href="#cb70-4"></a> qux x</span></code></pre></div>
452451<div class="sourceCode" id="cb71"><pre class="sourceCode haskell fragment"><code class="sourceCode haskell"><span id="cb71-1"><a href="#cb71-1"></a>foo <span class="ot">=</span> <span class="kw">do</span></span>
453−<span id="cb71-2"><a href="#cb71-2"></a> a <span class="ot">&lt;-</span> bar</span>
454−<span id="cb71-3"><a href="#cb71-3"></a> b <span class="ot">&lt;-</span> qux a</span>
455−<span id="cb71-4"><a href="#cb71-4"></a> <span class="fu">return</span> b</span></code></pre></div>
452+<span id="cb71-2"><a href="#cb71-2"></a> <span class="co">-- (x :: a) &lt;- (bar :: Reader r a)</span></span>
453+<span id="cb71-3"><a href="#cb71-3"></a> x <span class="ot">&lt;-</span> bar</span>
454+<span id="cb71-4"><a href="#cb71-4"></a> <span class="co">-- (y :: b) &lt;- (qux x :: Reader r b)</span></span>
455+<span id="cb71-5"><a href="#cb71-5"></a> y <span class="ot">&lt;-</span> qux x</span>
456+<span id="cb71-6"><a href="#cb71-6"></a> <span class="fu">return</span> y</span></code></pre></div>
457+<div class="sourceCode" id="cb72"><pre class="sourceCode haskell fragment"><code class="sourceCode haskell"><span id="cb72-1"><a href="#cb72-1"></a>foo <span class="ot">=</span> bar <span class="op">&gt;&gt;=</span> \x <span class="ot">-&gt;</span> qux x <span class="op">&gt;&gt;=</span> <span class="fu">return</span></span></code></pre></div>
456458</section>
457459<section class="slide level2">
458460
459−<div class="sourceCode" id="cb72"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb72-1"><a href="#cb72-1"></a><span class="kw">type</span> <span class="dt">PricingEnv</span> <span class="ot">=</span> <span class="dt">Reader</span> <span class="dt">Markup</span></span>
460−<span id="cb72-2"><a href="#cb72-2"></a></span>
461−<span id="cb72-3"><a href="#cb72-3"></a><span class="ot">getCoffeePrice ::</span> <span class="dt">Coffee</span> <span class="ot">-&gt;</span> <span class="dt">PricingEnv</span> <span class="dt">Price</span></span>
462−<span id="cb72-4"><a href="#cb72-4"></a><span class="ot">getDiscount ::</span> <span class="dt">Coffee</span> <span class="ot">-&gt;</span> <span class="dt">PricingEnv</span> <span class="dt">Price</span></span>
463−<span id="cb72-5"><a href="#cb72-5"></a><span class="ot">getPayment ::</span> <span class="dt">Price</span> <span class="ot">-&gt;</span> <span class="dt">PricingEnv</span> <span class="dt">Payment</span></span>
464−<span id="cb72-6"><a href="#cb72-6"></a></span>
465−<span id="cb72-7"><a href="#cb72-7"></a><span class="ot">payForCoffee ::</span> <span class="dt">Coffee</span> <span class="ot">-&gt;</span> <span class="dt">PricingEnv</span> <span class="dt">Payment</span></span>
466−<span id="cb72-8"><a href="#cb72-8"></a>payForCoffee coffee <span class="ot">=</span></span>
467−<span id="cb72-9"><a href="#cb72-9"></a> coffee <span class="op">&gt;&gt;=</span> getCoffeePrice <span class="op">&gt;&gt;=</span> \coffeePrice <span class="ot">-&gt;</span></span>
468−<span id="cb72-10"><a href="#cb72-10"></a> coffee <span class="op">&gt;&gt;=</span> getDiscount <span class="op">&gt;&gt;=</span> \discount <span class="ot">-&gt;</span></span>
469−<span id="cb72-11"><a href="#cb72-11"></a> getPayment (coffeePrice <span class="op">-</span> discount)</span></code></pre></div>
470−<div class="sourceCode" id="cb73"><pre class="sourceCode haskell fragment"><code class="sourceCode haskell"><span id="cb73-1"><a href="#cb73-1"></a><span class="ot">payForCoffee ::</span> <span class="dt">Coffee</span> <span class="ot">-&gt;</span> <span class="dt">PricingEnv</span> <span class="dt">Payment</span></span>
471−<span id="cb73-2"><a href="#cb73-2"></a>payForCoffee coffee <span class="ot">=</span> <span class="kw">do</span></span>
472−<span id="cb73-3"><a href="#cb73-3"></a> coffeePrice <span class="ot">&lt;-</span> getCoffeePrice coffee</span>
473−<span id="cb73-4"><a href="#cb73-4"></a> discount <span class="ot">&lt;-</span> getDiscount coffee</span>
474−<span id="cb73-5"><a href="#cb73-5"></a> getPayment (coffeePrice <span class="op">-</span> discount)</span></code></pre></div>
475−</section>
476−<section id="let-statement" class="slide level2">
477−<h2>Let statement</h2>
478−<div class="sourceCode" id="cb74"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb74-1"><a href="#cb74-1"></a><span class="ot">payForCoffee ::</span> <span class="dt">Coffee</span> <span class="ot">-&gt;</span> <span class="dt">PricingEnv</span> <span class="dt">Payment</span></span>
461+<div class="sourceCode" id="cb73"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb73-1"><a href="#cb73-1"></a><span class="kw">type</span> <span class="dt">PricingEnv</span> <span class="ot">=</span> <span class="dt">Reader</span> <span class="dt">Markup</span></span>
462+<span id="cb73-2"><a href="#cb73-2"></a></span>
463+<span id="cb73-3"><a href="#cb73-3"></a><span class="ot">getCoffeePrice ::</span> <span class="dt">Coffee</span> <span class="ot">-&gt;</span> <span class="dt">PricingEnv</span> <span class="dt">Price</span></span>
464+<span id="cb73-4"><a href="#cb73-4"></a><span class="ot">getDiscount ::</span> <span class="dt">Coffee</span> <span class="ot">-&gt;</span> <span class="dt">PricingEnv</span> <span class="dt">Price</span></span>
465+<span id="cb73-5"><a href="#cb73-5"></a><span class="ot">getPayment ::</span> <span class="dt">Price</span> <span class="ot">-&gt;</span> <span class="dt">PricingEnv</span> <span class="dt">Payment</span></span>
466+<span id="cb73-6"><a href="#cb73-6"></a></span>
467+<span id="cb73-7"><a href="#cb73-7"></a><span class="ot">payForCoffee ::</span> <span class="dt">Coffee</span> <span class="ot">-&gt;</span> <span class="dt">PricingEnv</span> <span class="dt">Payment</span></span>
468+<span id="cb73-8"><a href="#cb73-8"></a>payForCoffee coffee <span class="ot">=</span></span>
469+<span id="cb73-9"><a href="#cb73-9"></a> coffee <span class="op">&gt;&gt;=</span> getCoffeePrice <span class="op">&gt;&gt;=</span> \coffeePrice <span class="ot">-&gt;</span></span>
470+<span id="cb73-10"><a href="#cb73-10"></a> coffee <span class="op">&gt;&gt;=</span> getDiscount <span class="op">&gt;&gt;=</span> \discount <span class="ot">-&gt;</span></span>
471+<span id="cb73-11"><a href="#cb73-11"></a> getPayment (coffeePrice <span class="op">-</span> discount)</span></code></pre></div>
472+<div class="sourceCode" id="cb74"><pre class="sourceCode haskell fragment"><code class="sourceCode haskell"><span id="cb74-1"><a href="#cb74-1"></a><span class="ot">payForCoffee ::</span> <span class="dt">Coffee</span> <span class="ot">-&gt;</span> <span class="dt">PricingEnv</span> <span class="dt">Payment</span></span>
479473<span id="cb74-2"><a href="#cb74-2"></a>payForCoffee coffee <span class="ot">=</span> <span class="kw">do</span></span>
480474<span id="cb74-3"><a href="#cb74-3"></a> coffeePrice <span class="ot">&lt;-</span> getCoffeePrice coffee</span>
481475<span id="cb74-4"><a href="#cb74-4"></a> discount <span class="ot">&lt;-</span> getDiscount coffee</span>
482476<span id="cb74-5"><a href="#cb74-5"></a> getPayment (coffeePrice <span class="op">-</span> discount)</span></code></pre></div>
483−<div class="sourceCode" id="cb75"><pre class="sourceCode haskell fragment"><code class="sourceCode haskell"><span id="cb75-1"><a href="#cb75-1"></a><span class="ot">payForCoffee ::</span> <span class="dt">Coffee</span> <span class="ot">-&gt;</span> <span class="dt">PricingEnv</span> <span class="dt">Payment</span></span>
477+</section>
478+<section id="let-statement" class="slide level2">
479+<h2>Let statement</h2>
480+<div class="sourceCode" id="cb75"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb75-1"><a href="#cb75-1"></a><span class="ot">payForCoffee ::</span> <span class="dt">Coffee</span> <span class="ot">-&gt;</span> <span class="dt">PricingEnv</span> <span class="dt">Payment</span></span>
484481<span id="cb75-2"><a href="#cb75-2"></a>payForCoffee coffee <span class="ot">=</span> <span class="kw">do</span></span>
485482<span id="cb75-3"><a href="#cb75-3"></a> coffeePrice <span class="ot">&lt;-</span> getCoffeePrice coffee</span>
486483<span id="cb75-4"><a href="#cb75-4"></a> discount <span class="ot">&lt;-</span> getDiscount coffee</span>
487−<span id="cb75-5"><a href="#cb75-5"></a> <span class="kw">let</span> amount <span class="ot">=</span> coffeePrice <span class="op">-</span> discount</span>
488−<span id="cb75-6"><a href="#cb75-6"></a> getPayment amount</span></code></pre></div>
484+<span id="cb75-5"><a href="#cb75-5"></a> getPayment (coffeePrice <span class="op">-</span> discount)</span></code></pre></div>
485+<div class="sourceCode" id="cb76"><pre class="sourceCode haskell fragment"><code class="sourceCode haskell"><span id="cb76-1"><a href="#cb76-1"></a><span class="ot">payForCoffee ::</span> <span class="dt">Coffee</span> <span class="ot">-&gt;</span> <span class="dt">PricingEnv</span> <span class="dt">Payment</span></span>
486+<span id="cb76-2"><a href="#cb76-2"></a>payForCoffee coffee <span class="ot">=</span> <span class="kw">do</span></span>
487+<span id="cb76-3"><a href="#cb76-3"></a> coffeePrice <span class="ot">&lt;-</span> getCoffeePrice coffee</span>
488+<span id="cb76-4"><a href="#cb76-4"></a> discount <span class="ot">&lt;-</span> getDiscount coffee</span>
489+<span id="cb76-5"><a href="#cb76-5"></a> <span class="kw">let</span> amount <span class="ot">=</span> coffeePrice <span class="op">-</span> discount</span>
490+<span id="cb76-6"><a href="#cb76-6"></a> getPayment amount</span></code></pre></div>
489491</section>
490492<section class="slide level2">
491493
492−<div class="sourceCode" id="cb76"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb76-1"><a href="#cb76-1"></a><span class="kw">type</span> <span class="dt">PricingEnv</span> <span class="ot">=</span> <span class="dt">Reader</span> <span class="dt">Markup</span></span>
493−<span id="cb76-2"><a href="#cb76-2"></a><span class="kw">type</span> <span class="dt">Price</span> <span class="ot">=</span> <span class="dt">Int</span></span>
494−<span id="cb76-3"><a href="#cb76-3"></a></span>
495−<span id="cb76-4"><a href="#cb76-4"></a><span class="kw">data</span> <span class="dt">Coffee</span> <span class="ot">=</span> <span class="dt">Coffee</span> {<span class="ot"> getCoffeePrice ::</span> <span class="dt">Price</span> }</span>
496−<span id="cb76-5"><a href="#cb76-5"></a></span>
497−<span id="cb76-6"><a href="#cb76-6"></a><span class="ot">getCoffeePrice ::</span> <span class="dt">Coffee</span> <span class="ot">-&gt;</span> <span class="dt">PricingEnv</span> <span class="dt">Price</span></span></code></pre></div>
498−<div class="sourceCode" id="cb77"><pre class="sourceCode haskell fragment"><code class="sourceCode haskell"><span id="cb77-1"><a href="#cb77-1"></a><span class="kw">data</span> <span class="dt">Reader</span> r a <span class="ot">=</span> <span class="dt">Reader</span> {<span class="ot"> runReader ::</span> r <span class="ot">-&gt;</span> a}</span></code></pre></div>
499−<div class="sourceCode" id="cb78"><pre class="sourceCode haskell fragment"><code class="sourceCode haskell"><span id="cb78-1"><a href="#cb78-1"></a><span class="ot">ask ::</span> <span class="dt">Reader</span> r r</span>
500−<span id="cb78-2"><a href="#cb78-2"></a>ask <span class="ot">=</span> <span class="dt">Reader</span> (\r <span class="ot">-&gt;</span> r)</span></code></pre></div>
501−<div class="sourceCode" id="cb79"><pre class="sourceCode haskell fragment"><code class="sourceCode haskell"><span id="cb79-1"><a href="#cb79-1"></a><span class="ot">getCoffeePrice ::</span> <span class="dt">Coffee</span> <span class="ot">-&gt;</span> <span class="dt">PricingEnv</span> <span class="dt">Price</span></span>
502−<span id="cb79-2"><a href="#cb79-2"></a>getCoffeePrice coffee <span class="ot">=</span> <span class="kw">do</span></span>
503−<span id="cb79-3"><a href="#cb79-3"></a> markup <span class="ot">&lt;-</span> ask</span>
504−<span id="cb79-4"><a href="#cb79-4"></a> <span class="kw">let</span> coffePrice <span class="ot">=</span> getCoffeePrice coffee</span>
505−<span id="cb79-5"><a href="#cb79-5"></a> <span class="fu">return</span> (coffee <span class="op">+</span> markup)</span></code></pre></div>
494+<div class="sourceCode" id="cb77"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb77-1"><a href="#cb77-1"></a><span class="kw">type</span> <span class="dt">PricingEnv</span> <span class="ot">=</span> <span class="dt">Reader</span> <span class="dt">Markup</span></span>
495+<span id="cb77-2"><a href="#cb77-2"></a><span class="kw">type</span> <span class="dt">Price</span> <span class="ot">=</span> <span class="dt">Int</span></span>
496+<span id="cb77-3"><a href="#cb77-3"></a></span>
497+<span id="cb77-4"><a href="#cb77-4"></a><span class="kw">data</span> <span class="dt">Coffee</span> <span class="ot">=</span> <span class="dt">Coffee</span> {<span class="ot"> getCoffeePrice ::</span> <span class="dt">Price</span> }</span>
498+<span id="cb77-5"><a href="#cb77-5"></a></span>
499+<span id="cb77-6"><a href="#cb77-6"></a><span class="ot">getCoffeePrice ::</span> <span class="dt">Coffee</span> <span class="ot">-&gt;</span> <span class="dt">PricingEnv</span> <span class="dt">Price</span></span></code></pre></div>
500+<div class="sourceCode" id="cb78"><pre class="sourceCode haskell fragment"><code class="sourceCode haskell"><span id="cb78-1"><a href="#cb78-1"></a><span class="kw">data</span> <span class="dt">Reader</span> r a <span class="ot">=</span> <span class="dt">Reader</span> {<span class="ot"> runReader ::</span> r <span class="ot">-&gt;</span> a}</span></code></pre></div>
501+<div class="sourceCode" id="cb79"><pre class="sourceCode haskell fragment"><code class="sourceCode haskell"><span id="cb79-1"><a href="#cb79-1"></a><span class="ot">ask ::</span> <span class="dt">Reader</span> r r</span>
502+<span id="cb79-2"><a href="#cb79-2"></a>ask <span class="ot">=</span> <span class="dt">Reader</span> (\r <span class="ot">-&gt;</span> r)</span></code></pre></div>
503+<div class="sourceCode" id="cb80"><pre class="sourceCode haskell fragment"><code class="sourceCode haskell"><span id="cb80-1"><a href="#cb80-1"></a><span class="ot">getCoffeePrice ::</span> <span class="dt">Coffee</span> <span class="ot">-&gt;</span> <span class="dt">PricingEnv</span> <span class="dt">Price</span></span>
504+<span id="cb80-2"><a href="#cb80-2"></a>getCoffeePrice coffee <span class="ot">=</span> <span class="kw">do</span></span>
505+<span id="cb80-3"><a href="#cb80-3"></a> <span class="co">-- (markup :: Markup) &lt;- (ask :: PricingEnv Markup)</span></span>
506+<span id="cb80-4"><a href="#cb80-4"></a> markup <span class="ot">&lt;-</span> ask</span>
507+<span id="cb80-5"><a href="#cb80-5"></a> <span class="kw">let</span> coffePrice <span class="ot">=</span> getCoffeePrice coffee</span>
508+<span id="cb80-6"><a href="#cb80-6"></a> <span class="fu">return</span> (coffee <span class="op">+</span> markup)</span></code></pre></div>
506509</section>
507510<section class="slide level2">
508511
509−<div class="sourceCode" id="cb80"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb80-1"><a href="#cb80-1"></a><span class="kw">data</span> <span class="dt">Order</span> <span class="ot">=</span> <span class="dt">Order</span> {<span class="ot"> orderCoffee ::</span> <span class="dt">Coffee</span>,<span class="ot"> orderId ::</span> <span class="dt">Int</span> }</span></code></pre></div>
510−<div class="sourceCode" id="cb81"><pre class="sourceCode haskell fragment"><code class="sourceCode haskell"><span id="cb81-1"><a href="#cb81-1"></a><span class="ot">createOrder ::</span> <span class="dt">Coffee</span> <span class="ot">-&gt;</span> <span class="dt">Order</span></span></code></pre></div>
512+<div class="sourceCode" id="cb81"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb81-1"><a href="#cb81-1"></a><span class="kw">data</span> <span class="dt">Order</span> <span class="ot">=</span> <span class="dt">Order</span> {<span class="ot"> orderCoffee ::</span> <span class="dt">Coffee</span>,<span class="ot"> orderId ::</span> <span class="dt">Int</span> }</span></code></pre></div>
513+<div class="sourceCode" id="cb82"><pre class="sourceCode haskell fragment"><code class="sourceCode haskell"><span id="cb82-1"><a href="#cb82-1"></a><span class="ot">createOrder ::</span> <span class="dt">Coffee</span> <span class="ot">-&gt;</span> <span class="dt">Order</span></span></code></pre></div>
511514<p><span class="fragment">Откуда брать <code>orderId</code>?</span></p>
512−<div class="sourceCode" id="cb82"><pre class="sourceCode haskell fragment"><code class="sourceCode haskell"><span id="cb82-1"><a href="#cb82-1"></a><span class="ot">createOrder ::</span> <span class="dt">Coffee</span> <span class="ot">-&gt;</span> <span class="dt">Reader</span> <span class="dt">Int</span> <span class="dt">Order</span></span>
513−<span id="cb82-2"><a href="#cb82-2"></a>createOrder coffee <span class="ot">=</span> <span class="kw">do</span></span>
514−<span id="cb82-3"><a href="#cb82-3"></a> newId <span class="ot">&lt;-</span> ask</span>
515−<span id="cb82-4"><a href="#cb82-4"></a> <span class="fu">return</span> (<span class="dt">Order</span> coffee newId)</span></code></pre></div>
515+<div class="sourceCode" id="cb83"><pre class="sourceCode haskell fragment"><code class="sourceCode haskell"><span id="cb83-1"><a href="#cb83-1"></a><span class="ot">createOrder ::</span> <span class="dt">Coffee</span> <span class="ot">-&gt;</span> <span class="dt">Reader</span> <span class="dt">Int</span> <span class="dt">Order</span></span>
516+<span id="cb83-2"><a href="#cb83-2"></a>createOrder coffee <span class="ot">=</span> <span class="kw">do</span></span>
517+<span id="cb83-3"><a href="#cb83-3"></a> newId <span class="ot">&lt;-</span> ask</span>
518+<span id="cb83-4"><a href="#cb83-4"></a> <span class="fu">return</span> (<span class="dt">Order</span> coffee newId)</span></code></pre></div>
516519<p><span class="fragment">🎉</span></p>
517−<div class="sourceCode" id="cb83"><pre class="sourceCode haskell fragment"><code class="sourceCode haskell"><span id="cb83-1"><a href="#cb83-1"></a><span class="ot">createOrders ::</span> [<span class="dt">Coffee</span>] <span class="ot">-&gt;</span> <span class="dt">Reader</span> <span class="dt">Int</span> [<span class="dt">Order</span>]</span></code></pre></div>
518−<div class="sourceCode" id="cb84"><pre class="sourceCode haskell fragment"><code class="sourceCode haskell"><span id="cb84-1"><a href="#cb84-1"></a><span class="fu">mapM</span><span class="ot"> ::</span> (<span class="dt">Monad</span> m) <span class="ot">=&gt;</span> (a <span class="ot">-&gt;</span> m b) <span class="ot">-&gt;</span> [a] <span class="ot">-&gt;</span> m [b]</span></code></pre></div>
519−<div class="sourceCode" id="cb85"><pre class="sourceCode haskell fragment"><code class="sourceCode haskell"><span id="cb85-1"><a href="#cb85-1"></a>createOrders <span class="ot">=</span> <span class="fu">mapM</span> createOrder</span></code></pre></div>
520+<div class="sourceCode" id="cb84"><pre class="sourceCode haskell fragment"><code class="sourceCode haskell"><span id="cb84-1"><a href="#cb84-1"></a><span class="ot">createOrders ::</span> [<span class="dt">Coffee</span>] <span class="ot">-&gt;</span> <span class="dt">Reader</span> <span class="dt">Int</span> [<span class="dt">Order</span>]</span></code></pre></div>
521+<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="fu">mapM</span><span class="ot"> ::</span> (<span class="dt">Monad</span> m) <span class="ot">=&gt;</span> (a <span class="ot">-&gt;</span> m b) <span class="ot">-&gt;</span> [a] <span class="ot">-&gt;</span> m [b]</span></code></pre></div>
522+<div class="sourceCode" id="cb86"><pre class="sourceCode haskell fragment"><code class="sourceCode haskell"><span id="cb86-1"><a href="#cb86-1"></a>createOrders <span class="ot">=</span> <span class="fu">mapM</span> createOrder</span></code></pre></div>
520523</section>
521524<section class="slide level2">
522525
523−<div class="sourceCode" id="cb86"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb86-1"><a href="#cb86-1"></a><span class="ot">createOrders ::</span> [<span class="dt">Coffee</span>] <span class="ot">-&gt;</span> <span class="dt">Reader</span> <span class="dt">Int</span> [<span class="dt">Order</span>]</span>
524−<span id="cb86-2"><a href="#cb86-2"></a>createOrders <span class="ot">=</span> <span class="fu">mapM</span> createOrder</span></code></pre></div>
526+<div class="sourceCode" id="cb87"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb87-1"><a href="#cb87-1"></a><span class="ot">createOrders ::</span> [<span class="dt">Coffee</span>] <span class="ot">-&gt;</span> <span class="dt">Reader</span> <span class="dt">Int</span> [<span class="dt">Order</span>]</span>
527+<span id="cb87-2"><a href="#cb87-2"></a>createOrders <span class="ot">=</span> <span class="fu">mapM</span> createOrder</span></code></pre></div>
525528<p><span class="fragment">Все <code>id</code> будут одинаковые.</span></p>
526529<p><span class="fragment"><code>Reader</code> эквивалентно глобальной <strong>константе</strong>.</span></p>
527530<p><span class="fragment">Айдишники – скорее глобальная <strong>переменная</strong>.</span></p>
@@ -530,108 +533,121 @@
530533</section>
531534<section id="state" class="slide level2">
532535<h2>State!</h2>
533−<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="kw">data</span> <span class="dt">State</span> s a <span class="ot">=</span> <span class="op">...</span> <span class="co">-- s -- само состояние</span></span>
534−<span id="cb87-2"><a href="#cb87-2"></a></span>
535−<span id="cb87-3"><a href="#cb87-3"></a><span class="ot">get ::</span> <span class="dt">State</span> s s</span>
536−<span id="cb87-4"><a href="#cb87-4"></a><span class="ot">put ::</span> s <span class="ot">-&gt;</span> <span class="dt">State</span> s ()</span></code></pre></div>
537−<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="kw">data</span> <span class="dt">State</span> s a <span class="ot">=</span> <span class="dt">State</span> {<span class="ot"> runState ::</span> s <span class="ot">-&gt;</span> (a, s) }</span>
536+<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="kw">data</span> <span class="dt">State</span> s a <span class="ot">=</span> <span class="op">...</span> <span class="co">-- s -- само состояние</span></span>
538537<span id="cb88-2"><a href="#cb88-2"></a></span>
539538<span id="cb88-3"><a href="#cb88-3"></a><span class="ot">get ::</span> <span class="dt">State</span> s s</span>
540−<span id="cb88-4"><a href="#cb88-4"></a>get <span class="ot">=</span> <span class="dt">State</span> (\s <span class="ot">-&gt;</span> (s, s))</span>
541−<span id="cb88-5"><a href="#cb88-5"></a></span>
542−<span id="cb88-6"><a href="#cb88-6"></a><span class="ot">put ::</span> s <span class="ot">-&gt;</span> <span class="dt">State</span> s ()</span>
543−<span id="cb88-7"><a href="#cb88-7"></a>put s <span class="ot">=</span> <span class="dt">State</span> (\_ <span class="ot">-&gt;</span> ((), s))</span></code></pre></div>
539+<span id="cb88-4"><a href="#cb88-4"></a><span class="ot">put ::</span> s <span class="ot">-&gt;</span> <span class="dt">State</span> s ()</span></code></pre></div>
540+<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">data</span> <span class="dt">State</span> s a <span class="ot">=</span> <span class="dt">State</span> {<span class="ot"> runState ::</span> s <span class="ot">-&gt;</span> (a, s) }</span>
541+<span id="cb89-2"><a href="#cb89-2"></a></span>
542+<span id="cb89-3"><a href="#cb89-3"></a><span class="ot">get ::</span> <span class="dt">State</span> s s</span>
543+<span id="cb89-4"><a href="#cb89-4"></a>get <span class="ot">=</span> <span class="dt">State</span> (\s <span class="ot">-&gt;</span> (s, s))</span>
544+<span id="cb89-5"><a href="#cb89-5"></a></span>
545+<span id="cb89-6"><a href="#cb89-6"></a><span class="ot">put ::</span> s <span class="ot">-&gt;</span> <span class="dt">State</span> s ()</span>
546+<span id="cb89-7"><a href="#cb89-7"></a>put s <span class="ot">=</span> <span class="dt">State</span> (\_ <span class="ot">-&gt;</span> ((), s))</span></code></pre></div>
544547</section>
545548<section class="slide level2">
546549
547−<div class="sourceCode" id="cb89"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb89-1"><a href="#cb89-1"></a><span class="kw">data</span> <span class="dt">State</span> s a <span class="ot">=</span> <span class="dt">State</span> {<span class="ot"> runState ::</span> s <span class="ot">-&gt;</span> (a, s) }</span></code></pre></div>
548−<div class="sourceCode" id="cb90"><pre class="sourceCode haskell fragment"><code class="sourceCode haskell"><span id="cb90-1"><a href="#cb90-1"></a><span class="kw">class</span> <span class="dt">Monad</span> (<span class="dt">State</span> s) <span class="kw">where</span></span>
549−<span id="cb90-2"><a href="#cb90-2"></a> <span class="fu">return</span> x <span class="ot">=</span> <span class="dt">State</span> (\s <span class="ot">-&gt;</span> (x, s))</span>
550−<span id="cb90-3"><a href="#cb90-3"></a></span>
551−<span id="cb90-4"><a href="#cb90-4"></a><span class="ot"> (&gt;&gt;=) ::</span> <span class="dt">State</span> s a <span class="ot">-&gt;</span> (a <span class="ot">-&gt;</span> <span class="dt">State</span> s b) <span class="ot">-&gt;</span> <span class="dt">State</span> s b</span>
552−<span id="cb90-5"><a href="#cb90-5"></a> (<span class="dt">State</span> f) <span class="op">&gt;&gt;=</span> g <span class="ot">=</span> <span class="dt">State</span> go</span>
553−<span id="cb90-6"><a href="#cb90-6"></a> <span class="kw">where</span></span>
554−<span id="cb90-7"><a href="#cb90-7"></a> go s <span class="ot">=</span> runState (g a) s&#39;</span>
555−<span id="cb90-8"><a href="#cb90-8"></a> <span class="kw">where</span></span>
556−<span id="cb90-9"><a href="#cb90-9"></a> (a, s&#39;) <span class="ot">=</span> f s</span></code></pre></div>
550+<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">State</span> s a <span class="ot">=</span> <span class="dt">State</span> {<span class="ot"> runState ::</span> s <span class="ot">-&gt;</span> (a, s) }</span></code></pre></div>
551+<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="kw">class</span> <span class="dt">Monad</span> (<span class="dt">State</span> s) <span class="kw">where</span></span>
552+<span id="cb91-2"><a href="#cb91-2"></a> <span class="fu">return</span> x <span class="ot">=</span> <span class="dt">State</span> (\s <span class="ot">-&gt;</span> (x, s))</span>
553+<span id="cb91-3"><a href="#cb91-3"></a></span>
554+<span id="cb91-4"><a href="#cb91-4"></a><span class="ot"> (&gt;&gt;=) ::</span> <span class="dt">State</span> s a <span class="ot">-&gt;</span> (a <span class="ot">-&gt;</span> <span class="dt">State</span> s b) <span class="ot">-&gt;</span> <span class="dt">State</span> s b</span>
555+<span id="cb91-5"><a href="#cb91-5"></a> (<span class="dt">State</span> f) <span class="op">&gt;&gt;=</span> g <span class="ot">=</span> <span class="dt">State</span> go</span>
556+<span id="cb91-6"><a href="#cb91-6"></a> <span class="kw">where</span></span>
557+<span id="cb91-7"><a href="#cb91-7"></a> go s <span class="ot">=</span> runState (g a) s&#39;</span>
558+<span id="cb91-8"><a href="#cb91-8"></a> <span class="kw">where</span></span>
559+<span id="cb91-9"><a href="#cb91-9"></a> (a, s&#39;) <span class="ot">=</span> f s</span></code></pre></div>
557560</section>
558561<section class="slide level2">
559562
560563<h3 id="айдишники">Айдишники!</h3>
561−<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="ot">getNewId ::</span> <span class="dt">State</span> <span class="dt">Int</span> <span class="dt">Int</span></span>
562−<span id="cb91-2"><a href="#cb91-2"></a>getNewId <span class="ot">=</span> <span class="kw">do</span></span>
563−<span id="cb91-3"><a href="#cb91-3"></a> newId <span class="ot">&lt;-</span> get</span>
564−<span id="cb91-4"><a href="#cb91-4"></a> put (newId <span class="op">+</span> <span class="dv">1</span>)</span>
565−<span id="cb91-5"><a href="#cb91-5"></a> <span class="fu">return</span> newId</span></code></pre></div>
564+<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">getNewId ::</span> <span class="dt">State</span> <span class="dt">Int</span> <span class="dt">Int</span></span>
565+<span id="cb92-2"><a href="#cb92-2"></a>getNewId <span class="ot">=</span> <span class="kw">do</span></span>
566+<span id="cb92-3"><a href="#cb92-3"></a> newId <span class="ot">&lt;-</span> get</span>
567+<span id="cb92-4"><a href="#cb92-4"></a> put (newId <span class="op">+</span> <span class="dv">1</span>)</span>
568+<span id="cb92-5"><a href="#cb92-5"></a> <span class="fu">return</span> newId</span></code></pre></div>
566569<p><span class="fragment">– Это какой-то процедурный языке получается!</span></p>
567570<p><span class="fragment">– Лучше!*</span></p>
568−<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">createOrder ::</span> <span class="dt">Coffee</span> <span class="ot">-&gt;</span> <span class="dt">State</span> <span class="dt">Int</span> <span class="dt">Order</span></span>
569−<span id="cb92-2"><a href="#cb92-2"></a>createOrder coffee <span class="ot">=</span> <span class="kw">do</span></span>
570−<span id="cb92-3"><a href="#cb92-3"></a> newId <span class="ot">&lt;-</span> getNewId</span>
571−<span id="cb92-4"><a href="#cb92-4"></a> <span class="fu">return</span> (<span class="dt">Order</span> coffee newId)</span>
572−<span id="cb92-5"><a href="#cb92-5"></a></span>
573−<span id="cb92-6"><a href="#cb92-6"></a><span class="ot">createOrders ::</span> [<span class="dt">Coffee</span>] <span class="ot">-&gt;</span> <span class="dt">State</span> <span class="dt">Int</span> [<span class="dt">Order</span>]</span>
574−<span id="cb92-7"><a href="#cb92-7"></a>createOrders <span class="ot">=</span> <span class="fu">mapM</span> createOrder</span></code></pre></div>
571+<div class="sourceCode" id="cb93"><pre class="sourceCode haskell fragment"><code class="sourceCode haskell"><span id="cb93-1"><a href="#cb93-1"></a><span class="ot">createOrder ::</span> <span class="dt">Coffee</span> <span class="ot">-&gt;</span> <span class="dt">State</span> <span class="dt">Int</span> <span class="dt">Order</span></span>
572+<span id="cb93-2"><a href="#cb93-2"></a>createOrder coffee <span class="ot">=</span> <span class="kw">do</span></span>
573+<span id="cb93-3"><a href="#cb93-3"></a> newId <span class="ot">&lt;-</span> getNewId</span>
574+<span id="cb93-4"><a href="#cb93-4"></a> <span class="fu">return</span> (<span class="dt">Order</span> coffee newId)</span>
575+<span id="cb93-5"><a href="#cb93-5"></a></span>
576+<span id="cb93-6"><a href="#cb93-6"></a><span class="ot">createOrders ::</span> [<span class="dt">Coffee</span>] <span class="ot">-&gt;</span> <span class="dt">State</span> <span class="dt">Int</span> [<span class="dt">Order</span>]</span>
577+<span id="cb93-7"><a href="#cb93-7"></a>createOrders <span class="ot">=</span> <span class="fu">mapM</span> createOrder</span></code></pre></div>
575578</section>
576579<section id="еще-монады" class="slide level2">
577580<h2>Еще монады!</h2>
578−<div class="sourceCode" id="cb93"><pre class="sourceCode haskell fragment"><code class="sourceCode haskell"><span id="cb93-1"><a href="#cb93-1"></a><span class="kw">class</span> <span class="dt">Monad</span> [] <span class="kw">where</span></span>
579−<span id="cb93-2"><a href="#cb93-2"></a> <span class="fu">return</span> x <span class="ot">=</span> [x]</span>
580−<span id="cb93-3"><a href="#cb93-3"></a></span>
581−<span id="cb93-4"><a href="#cb93-4"></a><span class="ot"> (&gt;&gt;=) ::</span> [a] <span class="ot">-&gt;</span> (a <span class="ot">-&gt;</span> [b]) <span class="ot">-&gt;</span> [b]</span>
582−<span id="cb93-5"><a href="#cb93-5"></a> [] <span class="op">&gt;&gt;=</span> _ <span class="ot">=</span> []</span>
583−<span id="cb93-6"><a href="#cb93-6"></a> (a <span class="op">:</span> aa) <span class="op">&gt;&gt;=</span> f <span class="ot">=</span> f a <span class="op">&lt;&gt;</span> (a <span class="op">&gt;&gt;=</span> f)</span></code></pre></div>
581+<div class="sourceCode" id="cb94"><pre class="sourceCode haskell fragment"><code class="sourceCode haskell"><span id="cb94-1"><a href="#cb94-1"></a><span class="kw">class</span> <span class="dt">Monad</span> [] <span class="kw">where</span></span>
582+<span id="cb94-2"><a href="#cb94-2"></a> <span class="fu">return</span> x <span class="ot">=</span> [x]</span>
583+<span id="cb94-3"><a href="#cb94-3"></a></span>
584+<span id="cb94-4"><a href="#cb94-4"></a><span class="ot"> (&gt;&gt;=) ::</span> [a] <span class="ot">-&gt;</span> (a <span class="ot">-&gt;</span> [b]) <span class="ot">-&gt;</span> [b]</span>
585+<span id="cb94-5"><a href="#cb94-5"></a> [] <span class="op">&gt;&gt;=</span> _ <span class="ot">=</span> []</span>
586+<span id="cb94-6"><a href="#cb94-6"></a> (a <span class="op">:</span> aa) <span class="op">&gt;&gt;=</span> f <span class="ot">=</span> f a <span class="op">&lt;&gt;</span> (a <span class="op">&gt;&gt;=</span> f)</span></code></pre></div>
584587<p><span class="fragment">Контекст недетерменированности (нескольких вариантов)</span></p>
585−<div class="sourceCode" id="cb94"><pre class="sourceCode haskell fragment"><code class="sourceCode haskell"><span id="cb94-1"><a href="#cb94-1"></a>grid <span class="ot">=</span> <span class="kw">do</span></span>
586−<span id="cb94-2"><a href="#cb94-2"></a> x <span class="ot">&lt;-</span> [<span class="dv">1</span><span class="op">..</span><span class="dv">5</span>]</span>
587−<span id="cb94-3"><a href="#cb94-3"></a> y <span class="ot">&lt;-</span> [<span class="dv">1</span><span class="op">..</span><span class="dv">5</span>]</span>
588−<span id="cb94-4"><a href="#cb94-4"></a> <span class="fu">return</span> (x, y)</span>
589−<span id="cb94-5"><a href="#cb94-5"></a></span>
590−<span id="cb94-6"><a href="#cb94-6"></a><span class="co">-- [(1,1),(1,2),(1,3),(1,4),(1,5),(2,1),(2,2),(2,3),(2,4),(2,5),(3,1),(3,2),(3,3),(3,4),(3,5),(4,1),(4,2),(4,3),(4,4),(4,5),(5,1),(5,2),(5,3),(5,4),(5,5)]</span></span></code></pre></div>
588+<div class="sourceCode" id="cb95"><pre class="sourceCode haskell fragment"><code class="sourceCode haskell"><span id="cb95-1"><a href="#cb95-1"></a>grid <span class="ot">=</span> <span class="kw">do</span></span>
589+<span id="cb95-2"><a href="#cb95-2"></a> x <span class="ot">&lt;-</span> [<span class="dv">1</span><span class="op">..</span><span class="dv">5</span>]</span>
590+<span id="cb95-3"><a href="#cb95-3"></a> y <span class="ot">&lt;-</span> [<span class="dv">1</span><span class="op">..</span><span class="dv">5</span>]</span>
591+<span id="cb95-4"><a href="#cb95-4"></a> <span class="fu">return</span> (x, y)</span>
592+<span id="cb95-5"><a href="#cb95-5"></a></span>
593+<span id="cb95-6"><a href="#cb95-6"></a><span class="co">-- [(1,1),(1,2),(1,3),(1,4),(1,5),(2,1),(2,2),(2,3),(2,4),(2,5),(3,1),(3,2),(3,3),(3,4),(3,5),(4,1),(4,2),(4,3),(4,4),(4,5),(5,1),(5,2),(5,3),(5,4),(5,5)]</span></span></code></pre></div>
591594</section>
592595<section class="slide level2">
593596
594597<p>Тривиальная монада</p>
595−<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="kw">data</span> <span class="dt">Identity</span> a <span class="ot">=</span> <span class="dt">Identity</span> {<span class="ot"> runIdentity ::</span> a }</span>
596−<span id="cb95-2"><a href="#cb95-2"></a></span>
597−<span id="cb95-3"><a href="#cb95-3"></a><span class="kw">class</span> <span class="dt">Monad</span> <span class="dt">Identity</span> <span class="kw">where</span></span>
598−<span id="cb95-4"><a href="#cb95-4"></a> <span class="fu">return</span> x <span class="ot">=</span> <span class="dt">Identity</span> x</span>
599−<span id="cb95-5"><a href="#cb95-5"></a></span>
600−<span id="cb95-6"><a href="#cb95-6"></a><span class="ot"> (&gt;&gt;=) ::</span> <span class="dt">Identity</span> a <span class="ot">-&gt;</span> (a <span class="ot">-&gt;</span> <span class="dt">Identity</span> b) <span class="ot">-&gt;</span> <span class="dt">Identity</span> b</span>
601−<span id="cb95-7"><a href="#cb95-7"></a> (<span class="dt">Identity</span> a) <span class="op">&gt;&gt;=</span> f <span class="ot">=</span> <span class="dt">Identity</span> (f a)</span></code></pre></div>
598+<div class="sourceCode" id="cb96"><pre class="sourceCode haskell fragment"><code class="sourceCode haskell"><span id="cb96-1"><a href="#cb96-1"></a><span class="kw">data</span> <span class="dt">Identity</span> a <span class="ot">=</span> <span class="dt">Identity</span> {<span class="ot"> runIdentity ::</span> a }</span>
599+<span id="cb96-2"><a href="#cb96-2"></a></span>
600+<span id="cb96-3"><a href="#cb96-3"></a><span class="kw">class</span> <span class="dt">Monad</span> <span class="dt">Identity</span> <span class="kw">where</span></span>
601+<span id="cb96-4"><a href="#cb96-4"></a> <span class="fu">return</span> x <span class="ot">=</span> <span class="dt">Identity</span> x</span>
602+<span id="cb96-5"><a href="#cb96-5"></a></span>
603+<span id="cb96-6"><a href="#cb96-6"></a><span class="ot"> (&gt;&gt;=) ::</span> <span class="dt">Identity</span> a <span class="ot">-&gt;</span> (a <span class="ot">-&gt;</span> <span class="dt">Identity</span> b) <span class="ot">-&gt;</span> <span class="dt">Identity</span> b</span>
604+<span id="cb96-7"><a href="#cb96-7"></a> (<span class="dt">Identity</span> a) <span class="op">&gt;&gt;=</span> f <span class="ot">=</span> <span class="dt">Identity</span> (f a)</span></code></pre></div>
602605</section>
603606<section class="slide level2">
604607
605−<div class="sourceCode" id="cb96"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb96-1"><a href="#cb96-1"></a><span class="kw">class</span> <span class="dt">Applicative</span> m <span class="ot">=&gt;</span> <span class="dt">Monad</span> m <span class="kw">where</span></span>
606−<span id="cb96-2"><a href="#cb96-2"></a><span class="ot"> return ::</span> a <span class="ot">-&gt;</span> m a</span>
607−<span id="cb96-3"><a href="#cb96-3"></a><span class="ot"> (&gt;&gt;=) ::</span> m a <span class="ot">-&gt;</span> (a <span class="ot">-&gt;</span> m b) <span class="ot">-&gt;</span> m b</span></code></pre></div>
608+<div class="sourceCode" id="cb97"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb97-1"><a href="#cb97-1"></a><span class="kw">class</span> <span class="dt">Applicative</span> m <span class="ot">=&gt;</span> <span class="dt">Monad</span> m <span class="kw">where</span></span>
609+<span id="cb97-2"><a href="#cb97-2"></a><span class="ot"> return ::</span> a <span class="ot">-&gt;</span> m a</span>
610+<span id="cb97-3"><a href="#cb97-3"></a><span class="ot"> (&gt;&gt;=) ::</span> m a <span class="ot">-&gt;</span> (a <span class="ot">-&gt;</span> m b) <span class="ot">-&gt;</span> m b</span></code></pre></div>
608611<p><span class="fragment">Монада – перегрузка композиции функций.</span></p>
609−<div class="sourceCode" id="cb97"><pre class="sourceCode haskell fragment"><code class="sourceCode haskell"><span id="cb97-1"><a href="#cb97-1"></a><span class="kw">class</span> <span class="dt">Functor</span> m <span class="ot">=&gt;</span> <span class="dt">Applicative</span> m <span class="kw">where</span></span>
610−<span id="cb97-2"><a href="#cb97-2"></a><span class="ot"> pure ::</span> a <span class="ot">-&gt;</span> m a</span>
611−<span id="cb97-3"><a href="#cb97-3"></a><span class="ot"> (&lt;*&gt;) ::</span> m (a <span class="ot">-&gt;</span> b) <span class="ot">-&gt;</span> m a <span class="ot">-&gt;</span> m b</span></code></pre></div>
612+<div class="sourceCode" id="cb98"><pre class="sourceCode haskell fragment"><code class="sourceCode haskell"><span id="cb98-1"><a href="#cb98-1"></a><span class="kw">class</span> <span class="dt">Functor</span> m <span class="ot">=&gt;</span> <span class="dt">Applicative</span> m <span class="kw">where</span></span>
613+<span id="cb98-2"><a href="#cb98-2"></a><span class="ot"> pure ::</span> a <span class="ot">-&gt;</span> m a</span>
614+<span id="cb98-3"><a href="#cb98-3"></a><span class="ot"> (&lt;*&gt;) ::</span> m (a <span class="ot">-&gt;</span> b) <span class="ot">-&gt;</span> m a <span class="ot">-&gt;</span> m b</span></code></pre></div>
612615<p><span class="fragment">Аппликативный функтор – перегрузка применения функций.</span></p>
613616<p><span class="fragment">– Почему не <code>(a -&gt; b) -&gt; f a -&gt; f b</code>.</span></p>
614617<p><span class="fragment">– Это <code>fmap</code>. (И функции нескольких аргументов)</span></p>
615618</section>
616619<section class="slide level2">
617620
618−<div class="sourceCode" id="cb98"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb98-1"><a href="#cb98-1"></a>(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>
619−<div class="sourceCode" id="cb99"><pre class="sourceCode haskell fragment"><code class="sourceCode haskell"><span id="cb99-1"><a href="#cb99-1"></a>(a <span class="ot">-&gt;</span> (b <span class="ot">-&gt;</span> c)) <span class="ot">-&gt;</span> f a <span class="ot">-&gt;</span> f (b <span class="ot">-&gt;</span> c)</span></code></pre></div>
620−<div class="sourceCode" id="cb100"><pre class="sourceCode haskell fragment"><code class="sourceCode haskell"><span id="cb100-1"><a href="#cb100-1"></a><span class="ot">getMarkup ::</span> <span class="dt">Env</span> <span class="dt">Markup</span></span>
621−<span id="cb100-2"><a href="#cb100-2"></a><span class="ot">getPrice ::</span> <span class="dt">Env</span> <span class="dt">Price</span></span>
622−<span id="cb100-3"><a href="#cb100-3"></a><span class="ot">getPayment ::</span> <span class="dt">Markup</span> <span class="ot">-&gt;</span> <span class="dt">Price</span> <span class="ot">-&gt;</span> <span class="dt">Payment</span></span></code></pre></div>
623−<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="ot">payment ::</span> <span class="dt">Env</span> <span class="dt">Payment</span></span>
624−<span id="cb101-2"><a href="#cb101-2"></a>payment <span class="ot">=</span> <span class="fu">fmap</span> getPayment getMarkup <span class="op">&lt;*&gt;</span> getPrice</span></code></pre></div>
625−<div class="sourceCode" id="cb102"><pre class="sourceCode haskell fragment"><code class="sourceCode haskell"><span id="cb102-1"><a href="#cb102-1"></a>payment <span class="ot">=</span> <span class="fu">fmap</span> getPayment getMarkup <span class="op">&lt;*&gt;</span> getPrice</span>
626−<span id="cb102-2"><a href="#cb102-2"></a><span class="co">-- ^-------------^</span></span>
627−<span id="cb102-3"><a href="#cb102-3"></a><span class="co">-- Env Markup -&gt; Env (Price -&gt; Payment)</span></span></code></pre></div>
628−<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="op">&lt;$&gt;</span>) <span class="ot">=</span> <span class="fu">fmap</span></span></code></pre></div>
629−<div class="sourceCode" id="cb104"><pre class="sourceCode haskell fragment"><code class="sourceCode haskell"><span id="cb104-1"><a href="#cb104-1"></a>payment <span class="ot">=</span> getPayment <span class="op">&lt;$&gt;</span> getMarkup <span class="op">&lt;*&gt;</span> getPrice</span></code></pre></div>
621+<div class="sourceCode" id="cb99"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb99-1"><a href="#cb99-1"></a>(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>
622+<div class="sourceCode" id="cb100"><pre class="sourceCode haskell fragment"><code class="sourceCode haskell"><span id="cb100-1"><a href="#cb100-1"></a>(a <span class="ot">-&gt;</span> (b <span class="ot">-&gt;</span> c)) <span class="ot">-&gt;</span> f a <span class="ot">-&gt;</span> f (b <span class="ot">-&gt;</span> c)</span></code></pre></div>
623+<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="ot">getMarkup ::</span> <span class="dt">Env</span> <span class="dt">Markup</span></span>
624+<span id="cb101-2"><a href="#cb101-2"></a><span class="ot">getPrice ::</span> <span class="dt">Env</span> <span class="dt">Price</span></span>
625+<span id="cb101-3"><a href="#cb101-3"></a><span class="ot">getPayment ::</span> <span class="dt">Markup</span> <span class="ot">-&gt;</span> <span class="dt">Price</span> <span class="ot">-&gt;</span> <span class="dt">Payment</span></span></code></pre></div>
626+<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="ot">payment ::</span> <span class="dt">Env</span> <span class="dt">Payment</span></span>
627+<span id="cb102-2"><a href="#cb102-2"></a>payment <span class="ot">=</span> <span class="fu">fmap</span> getPayment getMarkup <span class="op">&lt;*&gt;</span> getPrice</span></code></pre></div>
628+<div class="sourceCode" id="cb103"><pre class="sourceCode haskell fragment"><code class="sourceCode haskell"><span id="cb103-1"><a href="#cb103-1"></a>payment <span class="ot">=</span> <span class="fu">fmap</span> getPayment getMarkup <span class="op">&lt;*&gt;</span> getPrice</span>
629+<span id="cb103-2"><a href="#cb103-2"></a><span class="co">-- ^-------------^</span></span>
630+<span id="cb103-3"><a href="#cb103-3"></a><span class="co">-- Env Markup -&gt; Env (Price -&gt; Payment)</span></span></code></pre></div>
631+<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="op">&lt;$&gt;</span>) <span class="ot">=</span> <span class="fu">fmap</span></span></code></pre></div>
632+<div class="sourceCode" id="cb105"><pre class="sourceCode haskell fragment"><code class="sourceCode haskell"><span id="cb105-1"><a href="#cb105-1"></a>payment <span class="ot">=</span> getPayment <span class="op">&lt;$&gt;</span> getMarkup <span class="op">&lt;*&gt;</span> getPrice</span></code></pre></div>
630633</section>
631634<section class="slide level2">
632635
633−<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">(&lt;*&gt;) ::</span> m (a <span class="ot">-&gt;</span> b) <span class="ot">-&gt;</span> m a <span class="ot">-&gt;</span> m b</span>
634−<span id="cb105-2"><a href="#cb105-2"></a>f <span class="op">&lt;*&gt;</span> ma <span class="ot">=</span> ma <span class="op">&gt;&gt;=</span> \a <span class="ot">-&gt;</span> <span class="fu">fmap</span> (\f&#39; <span class="ot">-&gt;</span> f&#39; a) f</span></code></pre></div>
636+<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">(&lt;*&gt;) ::</span> m (a <span class="ot">-&gt;</span> b) <span class="ot">-&gt;</span> m a <span class="ot">-&gt;</span> m b</span>
637+<span id="cb106-2"><a href="#cb106-2"></a>mf <span class="op">&lt;*&gt;</span> ma <span class="ot">=</span> <span class="kw">do</span></span>
638+<span id="cb106-3"><a href="#cb106-3"></a> f <span class="ot">&lt;-</span> mf</span>
639+<span id="cb106-4"><a href="#cb106-4"></a> a <span class="ot">&lt;-</span> ma</span>
640+<span id="cb106-5"><a href="#cb106-5"></a> <span class="fu">return</span> (f a)</span></code></pre></div>
641+<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="ot">ap ::</span> <span class="dt">Monad</span> m <span class="ot">=&gt;</span> m (a <span class="ot">-&gt;</span> b) <span class="ot">-&gt;</span> m a <span class="ot">-&gt;</span> m b</span>
642+<span id="cb107-2"><a href="#cb107-2"></a>ap mf ma <span class="ot">=</span> <span class="kw">do</span></span>
643+<span id="cb107-3"><a href="#cb107-3"></a> f <span class="ot">&lt;-</span> mf</span>
644+<span id="cb107-4"><a href="#cb107-4"></a> a <span class="ot">&lt;-</span> ma</span>
645+<span id="cb107-5"><a href="#cb107-5"></a> <span class="fu">return</span> (f a)</span></code></pre></div>
646+<div class="sourceCode" id="cb108"><pre class="sourceCode haskell fragment"><code class="sourceCode haskell"><span id="cb108-1"><a href="#cb108-1"></a><span class="kw">instance</span> <span class="dt">Monad</span> <span class="op">...</span> <span class="kw">where</span> <span class="op">...</span></span>
647+<span id="cb108-2"><a href="#cb108-2"></a></span>
648+<span id="cb108-3"><a href="#cb108-3"></a><span class="kw">instance</span> <span class="dt">Applicative</span> <span class="op">...</span> <span class="kw">where</span></span>
649+<span id="cb108-4"><a href="#cb108-4"></a> <span class="fu">pure</span> <span class="ot">=</span> <span class="fu">return</span></span>
650+<span id="cb108-5"><a href="#cb108-5"></a> (<span class="op">&lt;*&gt;</span>) <span class="ot">=</span> ap</span></code></pre></div>
635651</section></section>
636652 </div>
637653 </div>
3.md+56−32
@@ -258,7 +258,7 @@ instance Monad (Either e) where
258258instance Monad WithLog where
259259 (<=<) f g x = WithLog x3 (log1 <> log2)
260260 where
261− (WithLog x2 log1) = g x1
261+ (WithLog x2 log1) = g x
262262 (WithLog x3 log2) = f x2
263263```
264264
@@ -312,8 +312,8 @@ buyCoffee order = getCoffee order >>= payForCoffee
312312```
313313
314314```{ .haskell .fragment }
315−maybeBuyCoffee :: Myabe Order -> Maybe Payment
316−maybeBuyCoffee order = order >>= buyCoffee
315+maybeBuyCoffee :: Maybe Order -> Maybe Payment
316+maybeBuyCoffee mOrder = mOrder >>= buyCoffee
317317```
318318
319319```{ .haskell .fragment }
@@ -339,16 +339,16 @@ maybeBuyCoffee order = order >>= buyCoffee
339339
340340```{ .haskell }
341341(>>=) :: Monad m => m b -> (b -> m c) -> m c
342−(>>=) mb f = ( (\() -> mb) >=> f ) ()
342+(>>=) mb bmc = ( (\() -> mb) >=> bmc ) ()
343343```
344344
345345```{ .haskell .fragment }
346−(>>=) mb f = ( (\() -> mb) >=> f ) ()
347−-- () -> m b |
348−-- b -> m c
346+(>>=) mb bmc = ( (\() -> mb) >=> bmc ) ()
347+-- () -> m b |
348+-- b -> m c
349349--
350−-- ^-------------------^
351−-- () -> m c
350+-- ^-----------------------^
351+-- () -> m c
352352```
353353
354354---
@@ -433,31 +433,20 @@ data Reader r a = Reader
433433
434434[`r` -- то, что у нас в "окружении".]{ .fragment }
435435
436−```{ .haskell .fragment }
437−getCoffee :: Order -> Reader Markup Coffee
438−payForCoffee :: Coffee -> Reader Markup Payment
439−```
440−
441−```{ .haskell .fragment }
442−payment :: Payment
443−payment = runReader (payForCoffee coffee) markup
444−```
445−
446436---
447437
448438```{ .haskell }
449439data Reader r a = Reader { runReader :: r -> a }
450440
451−getCoffee :: Order -> Reader Markup Coffee
452−payForCoffee :: Coffee -> Reader Markup Payment
441+getCoffee :: Order -> Markup -> Coffee
442+payForCoffee :: Coffee -> Markup -> Payment
453443```
454444
455445```{ .haskell .fragment }
456−buyCoffee :: Order -> Reader Markup Payment
457−buyCoffee = payForCoffee <=< getCoffee
446+getCoffee :: Order -> Reader Markup Coffee
447+payForCoffee :: Coffee -> Reader Markup Payment
458448```
459449
460−
461450```{ .haskell .fragment }
462451type PricingEnv = Reader Markup
463452```
@@ -465,10 +454,18 @@ type PricingEnv = Reader Markup
465454```{ .haskell .fragment }
466455getCoffee :: Order -> PricingEnv Coffee
467456payForCoffee :: Coffee -> PricingEnv Payment
457+```
458+
459+```{ .haskell .fragment }
468460buyCoffee :: Order -> PricingEnv Payment
469461buyCoffee = payForCoffee <=< getCoffee
470462```
471463
464+```{ .haskell .fragment }
465+payment :: Payment
466+payment = runReader (buyCoffee order) markup
467+```
468+
472469---
473470
474471```{ .haskell }
@@ -533,20 +530,27 @@ bar :: Reader r a
533530qux :: a -> Reader r b
534531
535532foo :: Reader r b
536−foo = bar >>= \a -> qux a
533+foo = bar >>= \x -> qux x
537534```
538535
539536```{ .haskell .fragment }
540537foo = do
541− a <- bar
542− qux a
538+ -- (x :: a) <- (bar :: Reader r a)
539+ x <- bar
540+ qux x
543541```
544542
545543```{ .haskell .fragment }
546544foo = do
547− a <- bar
548− b <- qux a
549− return b
545+ -- (x :: a) <- (bar :: Reader r a)
546+ x <- bar
547+ -- (y :: b) <- (qux x :: Reader r b)
548+ y <- qux x
549+ return y
550+```
551+
552+```{ .haskell .fragment }
553+foo = bar >>= \x -> qux x >>= return
550554```
551555
552556---
@@ -618,6 +622,7 @@ ask = Reader (\r -> r)
618622```{ .haskell .fragment }
619623getCoffeePrice :: Coffee -> PricingEnv Price
620624getCoffeePrice coffee = do
625+ -- (markup :: Markup) <- (ask :: PricingEnv Markup)
621626 markup <- ask
622627 let coffePrice = getCoffeePrice coffee
623628 return (coffee + markup)
@@ -835,7 +840,26 @@ payment = getPayment <$> getMarkup <*> getPrice
835840
836841---
837842
838−```{ .haskell .fragment }
843+```{ .haskell }
839844(<*>) :: m (a -> b) -> m a -> m b
840−f <*> ma = ma >>= \a -> fmap (\f' -> f' a) f
845+mf <*> ma = do
846+ f <- mf
847+ a <- ma
848+ return (f a)
849+```
850+
851+```{ .haskell .fragment }
852+ap :: Monad m => m (a -> b) -> m a -> m b
853+ap mf ma = do
854+ f <- mf
855+ a <- ma
856+ return (f a)
857+```
858+
859+```{ .haskell .fragment }
860+instance Monad ... where ...
861+
862+instance Applicative ... where
863+ pure = return
864+ (<*>) = ap
841865```