git.iko.soy/ikoHSE/sc-lectures
on master help sign in
ikoHSE/sc-lectures/1_old.html
887 lines 34 kB history raw
1<!doctype html>
2<html>
4<head>
5 <meta charset="utf-8">
6 <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
8 <link rel="stylesheet" href="css/reset.css">
9 <link rel="stylesheet" href="css/reveal.css">
10 <link rel="stylesheet" href="css/theme/superblack.css">
12 <!-- Theme used for syntax highlighting of code -->
13 <link rel="stylesheet" href="lib/css/monokai.css">
15 <!-- Printing and PDF exports -->
16 <script>
17 var link = document.createElement('link');
18 link.rel = 'stylesheet';
19 link.type = 'text/css';
20 link.href = window.location.search.match(/print-pdf/gi) ? 'css/print/pdf.css' : 'css/print/paper.css';
21 document.getElementsByTagName('head')[0].appendChild(link);
22 </script>
23</head>
25<body>
26 <div class="reveal">
27 <div class="slides">
28 <section>
29 <h2>Функциональное программирование</h2>
30 <aside class="notes" data-markdown>
31 Функциональное программирование это не про использование map filter reduce.
33 Функциональное программирование это вообще ортогонально к ооп.
35 ИМХО проблема с ООП -- наследование (которое тоже ортогонально к ООП) -- нет разграничения между абстракцией и
36 реализацией.
38 и вообще обзывание это функциональным программированием -- не совсем правильно.
40 то, что мы сейчас будем пытаться сделать -- сделать код более переиспользуемым.
42 сделать наши данные максимально тупыми => переиспользуемыми.
44 пытаться комбинировать слишком умные куски -- не получится -- слишком сложно.
46 мы хотим сделать простые куски, которые просто комбинировать и еще чтобы компилятор проверял эти наши
47 комбинации на валидность.
48 </aside>
49 </section>
50 <section data-markdown>
51 Функциональное программирование:
52 > функции -- это тоже данные.
54 `Int -> Bool` (функция) -- ровно такие же данные как и `Int`. Их также можно складывать в структуры,
55 передавать как аргументы и т. п.
56 </section>
58 <section>
59 <section>
60 <h1>нотация</h1>
61 </section>
62 <section>
63 <table width="100%">
64 <tr>
65 <td>
66 <pre>
67 <code class="java">int x;</code>
68 </pre>
69 </td>
70 <td>
71 <pre>
72 <code class="haskell">x :: Int</code>
73 </pre>
74 </td>
75 </tr>
76 <tr class="fragment">
77 <td>
78 <pre>
79 <code class="java">int f(int x)</code>
80 </pre>
81 </td>
82 <td>
83 <pre>
84 <code class="haskell">f :: Int -> Int</code>
85 </pre>
86 </td>
87 </tr>
88 <tr class="fragment">
89 <td>
90 <pre>
91 <code class="java">static &lt;T&gt; T f(T x)</code>
92 </pre>
94 </td>
95 <td>
96 <pre>
97 <code class="haskell">f :: a -> a</code>
98 </pre>
99 </td>
100 </tr>
101 </table>
102 </section>
103 <section>
104 <table width="100%">
105 <tr>
106 <td>
107 <pre>
108 <code class="java">static &lt;T&gt; T f(T x)</code>
109 </pre>
110 </td>
111 <td>
112 <pre>
113 <code class="haskell">f :: a -> a</code>
114 </pre>
115 </td>
116 </tr>
117 <tr>
118 <td class="fragment">
119 <pre>
120 <code class="java">f(x);</code>
121 </pre>
122 </td>
123 <td class="fragment">
124 <pre>
125 <code class="haskell">f x</code>
126 </pre>
127 </td>
128 </tr>
129 <tr class="fragment">
130 <td>
131 <pre>
132 <code class="java">f(x, y);</code>
133 </pre>
134 </td>
135 <td>
136 <pre>
137 <code class="haskell">f x y</code>
138 </pre>
139 <pre class="fragment">
140 <code class="haskell">f x y = (f x) y</code>
141 </pre>
142 <aside class="notes">
143 Left-associative
144 Currying
145 </aside>
146 </td>
147 </td>
148 </tr>
149 </table>
150 </section>
151 <section>
152 <table width="100%">
153 <tr>
154 <td>
155 <pre>
156 <code class="java">static &lt;T&gt; T f(T x)
157static &lt;T&gt; T g(T x)</code>
158 </pre>
159 </td>
160 <td>
161 <pre>
162 <code class="haskell">f :: a -> a
163g :: a -> a</code>
164 </pre>
165 </td>
166 </tr>
167 <tr class="fragment">
168 <td>
169 <pre>
170 <code class="java">f(g(x));
171g(f(x));</code>
172 </pre>
173 </td>
174 <td class="fragment">
175 <pre>
176 <code class="haskell">f (g x)
177g (f x)</code>
178 </pre>
179 </td>
180 </tr>
181 </table>
182 </section>
183 </section>
184 <section>
185 <section>
186 <h1>
187 Композиция
188 </h1>
189 </section>
190 <section>
191 <pre><code class="haskell">f :: a -> a
192g :: a -> a</code></pre>
193 <pre class="fragment"><code class="haskell">f (g x)</code></pre>
194 <pre class="fragment"><code class="haskell">(f . g) x == f (g x)</code></pre>
195 <pre class="fragment"><code class="haskell">h = f . g
196h x == f (g x)</code></pre>
197 </section>
198 <section>
199 <pre><code class="haskell">f :: a -> a
200g :: a -> a
202h :: a -> a
203h = f . g</code></pre>
205 <h3 class="fragment">моноид</h3>
207 <aside class="notes" data-markdown>
208 моноид -- у тебя есть две штуки одного типа и ты можешь получить еще одну
209 штуку такого же
210 типа.
212 Это очень простой способ рождения сложности из простоты
214 причем тип h выводится из определения. Нам его указывать не надо.
216 если у нас изначальные маленькие кусочки хорошо описаны, то порожденные большие кусочки будут автоматически
217 хорошо описанными.
218 </aside>
219 </section>
220 <section>
221 <h3>
222 Моноид
223 </h3>
225 <p class="fragment">
226 Бинарная асоциативная операция
227 </p>
229 <pre><code class="haskell fragment">(.) :: (a -> a) -> (a -> a) -> (a -> a)</code></pre>
231 <p class="fragment">
232 Нейтральный элемент
233 </p>
235 <pre><code class="haskell fragment">id :: a -> a
236id x = x</code></pre>
237 </section>
238 </section>
239 </section>
240 <section>
241 <section>
242 <h2>Haskell</h2>
243 </section>
244 <section>
245 <h3>Чисто функционаьлный</h3>
246 <p class="fragment" data-markdown>Все что функция может сделать -- посмотреть на свои аргументы это вернуть
247 значение.</p>
248 <aside class="notes" data-markdown>Нельзя просто произвольно распечатать строку в консоль, нельзя просто
249 произвольно
250 отправить запрос на бд, нельзя просто произвольно изменить глобальную переменную.</aside>
251 </section>
252 <section>
253 <h3>Referential transparency</h3>
254 <h5>(Любую константу можно заменить на само значение)</h5>
255 <pre><code class="java fragment">int x = 8;
256int y = x++;
257System.out.println(y + " might be the same as " + y);</code></pre>
258 <pre><code class="java fragment">int x = 8;
259System.out.println(x++ + " might be the same as " + x++);</code></pre>
261 <aside class="notes" data-markdown>Сильно упрощает рефакторинг и понимание кода.</aside>
262 </section>
263 <section>
264 <h3>Нет переменных, циклов и условных переходов</h3>
266 <p class="fragment" data-markdown>
267 Зато есть константы и нормальная рекурсия
269 (А переходов вообще нет)
270 </p>
271 </section>
272 <section>
273 <h3>Очень ленивый</h3>
275 <pre><code class="haskell fragment">xs = [4, 1, 3, 2]
276xs' = sort xs
277print xs</code></pre>
279 <p class="fragment" data-markdown>
280 `xs'` не нужен чтобы распечатать `xs`, поэтому сортироваться ничто не будет.
282 (Зачем делать то, что можно не делать)
283 </p>
284 </section>
285 <section>
286 <p>Если хотите быстро и просто потыкаться, тут есть интерктивная штука:</p>
287 <a href="https://www.haskell.org">haskell.org</a>
288 </section>
289 </section>
290 <section>
291 <h2>Синтаксис</h2>
292 </section>
293 <section>
294 <section>
295 <h2>Функции</h2>
296 </section>
297 <section>
298 <pre><code class="haskell">add2 :: Int -> Int
299add2 x = x + 2</code></pre>
300 <p>Все функции и константы всегда обозначаются словами с маленькой буквы без пробелов.</p>
301 <p>(Константы это просто функции с нулем аргументов.)</p>
302 </section>
303 <section>
304 <h3>Pattern mathcing</h3>
305 <pre><code class="haskell">fixBuz :: Int -> String
306divide8 3 = "Fiz"
307divide8 5 = "Buz"
308divide8 15 = "FizBuz"
309divide8 _ = "Some other number"</code></pre>
311 <p data-markdown>
312 Так матчить можно произвольные структуры произвольного уровня вложенности.
314 `_` -- специальное название константы, которое говорит что вам все равно что в ней лежит.
315 </p>
316 <aside class="notes" data-markdown>
317 функции объявляются в несколькро строк. Первая -- обьявленик типа функции,
318 а последубщие -- реализация. В общем случае тип можно не указывать, но указывать тип у высказыванй на самом
319 верхнем уровне (не вложенные) считается хорошим тоном и улучшает выведение типов и ошибки компиляции.
321 У функции может быть несколько реализаций: какая из них вызовется зависит от значений передаваемых
322 аргументов. матчинг произхводится сверху вниз.
324 если в аргемантах написано слово с маленькой буквы, то значение аргумента биндится на эту константу.
325 </aside>
326 </section>
327 </section>
328 <section>
329 <section>
330 <h2>Структуры</h2>
331 </section>
332 <section>
333 <pre><code class="haskell">data Foo = Bar
334foo :: Bar
335foo = Bar</code></pre>
337 <p data-markdown>
338 `Foo` -- тип структуры. `Bar` -- конструктор структуры.
340 Тут у `Foo` всего одно значение `Bar`.
341 </p>
342 </section>
343 <section>
344 <h3>Произведение типов</h3>
345 <h5>(обычные поля структур)</h5>
346 <aside class="notes" data-markdown>
347 После констрктора можно укзать существующие типы, которые в нем храняться.
348 </aside>
350 <pre><code class="haskell">data PersonType = Person String Int</code></pre>
351 <pre><code class="haskell fragment">vasya :: PersonType
352vasya = Person "Vasya" 8
353-- тип можно не укзывать
354petya = Person "Petya" 5</code></pre>
355 <pre><code class="haskell fragment">getName :: PersonType -> String
356getName (Person name _) = name</code></pre>
357 <pre><code class="haskell fragment">greetPerson :: PersonType -> String
358greetPerson p = "Hello, " ++ getName p</code></pre>
359 <pre><code class="haskell fragment">greetPerson petya
360-- "Hello, Petya"</code></pre>
361 </section>
362 <section>
363 <h3>Еще немного функций</h3>
364 <pre><code class="haskell fragment">greetPerson :: PersonType -> String
365greetPerson p = "Hello, " ++ getName p</code></pre>
367 <pre><code class="haskell fragment">greetPerson :: PersonType -> String
368greetPerson p = "Hello, " ++ name
369 where
370 name = getName p</code></pre>
371 <pre><code class="haskell fragment">greetPerson :: PersonType -> String
372greetPerson p = "Hello, " ++ name
373 where
374 getName' (Person name _) = name
375 name = getName' p</code></pre>
376 </section>
377 <section>
378 <pre><code class="haskell">data PersonType = Person String Int
380getName :: PersonType -> String
381getName (Person name _) = name</code></pre>
382 <pre><code class="haskell fragment">greetName :: String -> String
383greetName name = "Hello, " ++ name</code></pre>
384 <pre><code class="haskell fragment">greetPerson :: PersonType -> String
385greetPerson p = greetName (getName p)</code></pre>
386 <pre><code class="haskell fragment">greetPerson :: PersonType -> String
387greetPerson = greetName . getName</code></pre>
388 <pre><code class="haskell fragment">greetPerson petya
389-- "Hello, Petya"</code></pre>
390 <pre><code class="haskell fragment">(greetName . getName) petya
391-- "Hello, Petya"</code></pre>
392 </section>
393 <section>
394 <h3>Суммы типов</h3>
395 <aside class="notes" data-markdown>
396 Функции нескольких аргументов -- странный синтаксис -- потом расскажу.
397 </aside>
399 <pre><code class="haskell fragment">data Bool = False | True</code></pre>
400 <pre><code class="haskell fragment">x :: Bool
401x = True
402y = False</code></pre>
404 <pre><code class="haskell fragment">ifThenElse :: (Bool, a, a) -> a</code></pre>
405 <pre><code class="haskell fragment">ifThenElse (True, a, _) = a
406ifThenElse (False, _, b) = b</code></pre>
407 <pre><code class="haskell fragment">ifThenElse (True, "Hello", "World")
408-- "Hello"</code></pre>
410 <pre><code class="haskell fragment">ifThenElse (False, "Hello", "World")
411-- "World"</code></pre>
413 </section>
414 <section>
415 <pre><code class="haskell">data CircleType = Circle Double Double Double
416data RectangleType = Rectangle Double Double Double Double
417</code></pre>
418 <pre><code class="haskell fragment">data Shape =
419 CircleShape CircleType | RectangleShape RectangleType</code></pre>
420 <pre><code class="haskell fragment">surface :: Shape -> Double</code></pre>
421 <pre><code class="haskell fragment">surface (CircleShape (Circle _ _ r)) =
422 pi * r ^ 2</code></pre>
423 <pre><code class="haskell fragment">surface (RectangleShape (Rectangle x1 y1 x2 y2)) =
424 (abs (x2 - x1)) * (abs (y2 - y1))</code></pre>
425 <pre><code class="haskell fragment">shape = CircleShape (Circle 0 0 2)
426surface shape
427-- 12.566370614359172
428</code></pre>
429 <pre><code class="haskell fragment">otherShape = RectangleShape (Rectangle 1 2 3 4)
430surface otherShape
431-- 4.0
432</code></pre>
433 </section>
434 </section>
435 <section>
436 <section>
437 <h2>И еще немного функций</h2>
438 </section>
439 <section>
440 <h3>Лямбда-выражения</h3>
442 <pre><code class="haskell fragment">add8 :: Int -> Int</code></pre>
443 <pre><code class="haskell fragment">add8 x = x + 8</code></pre>
444 <pre><code class="haskell fragment">add8 = \x -> x + 8</code></pre>
445 <p data-markdown class="fragment">
446 λ -- `\`
448 (λ печатать тяжело)</p>
450 <pre><code class="haskell fragment">foo :: (Int -> Int) -> Int</code></pre>
451 <pre><code class="haskell fragment">foo add8</code></pre>
452 <pre><code class="haskell fragment">foo (\x -> x + 8)</code></pre>
453 </section>
454 <section>
455 <h3>Давайте придумаем синтаксис для функции нескольких аргументов!</h3>
456 </section>
457 <section>
458 <pre><code class="haskell">x, y :: Int
459x = 42
460y = 69
461</code></pre>
463 <pre><code class="haskell fragment">xPlusY :: Int
464xPlusY = add x y</code></pre>
465 <p class="fragment" data-markdown>Применение функции -- лево-ассоциативно</p>
466 <pre><code class="haskell fragment">xPlusY = (add x) y</code></pre>
467 <pre><code class="haskell fragment">xPlusY = f y
468f = add x</code></pre>
469 <pre><code class="haskell fragment">f :: Int -> Int</code></pre>
470 <pre><code class="haskell fragment">add :: Int -> (Int -> Int)</code></pre>
471 </section>
472 <section>
473 <pre><code class="haskell">add :: Int -> (Int -> Int)</code></pre>
474 <p class="fragment" data-markdown>Тип `->` -- право-ассоциативный</p>
476 <pre><code class="haskell fragment">add :: Int -> Int -> Int</code></pre>
477 <pre><code class="haskell fragment">add a b = a + b</code></pre>
478 <pre><code class="haskell fragment">add = \a b -> a + b</code></pre>
479 </section>
480 <section>
481 <p>Любая функция берет строго один аргумент.</p>
483 <p>Функция нескольких аргументов все равно берет строго одтн аргумент и возвращает функцию, которая берет
484 следйющий.
485 </p>
487 <p>
488 <em>
489 (И из-за того, что применение функции лево-ассоциативно, вызов таких не трубует особого
490 синтаксиса.)
491 </em>
492 </p>
493 </section>
494 <section>
495 <h3>Currying</h3>
496 <pre><code class="haskell fragment">add :: Int -> Int -> Int
497add a b = a + b</code></pre>
499 <pre><code class="haskell fragment">add8 :: Int -> Int</code></pre>
500 <pre><code class="haskell fragment">add :: Int -> (Int -> Int)</code></pre>
501 <pre><code class="haskell fragment">add8 = add 8</code></pre>
502 <pre><code class="haskell fragment">add8 3
503-- 11</code></pre>
504 </section>
505 <section>
506 <h3>Funny fact</h3>
508 <p class="fragment" data-markdown>Оператор (например `+`) -- функция, название которой не содержит буквы и
509 цифры.</p>
510 <pre><code class="haskell fragment">x +&+ y = x + y</code></pre>
511 <pre><code class="haskell fragment">8 +&+ 9
512-- 17</code></pre>
514 </section>
515 <section>
516 <h3>Funny fact 2</h3>
518 <p class="fragment" data-markdown>Оператор можно превратить в функцию, окружив его скобками.</p>
519 <pre><code class="haskell fragment">add :: Int -> Int -> Int
520add x y = x + y</code></pre>
521 <pre><code class="haskell fragment">add = (+&+)</code></pre>
522 <pre><code class="haskell fragment">add = (+)</code></pre>
524 </section>
525 <section>
526 <h3>Funny fact 3</h3>
528 <p class="fragment" data-markdown>Функцию можно превратить в оператор, окружив ее обратными кавычками.</p>
529 <pre><code class="haskell fragment">add :: Int -> Int -> Int
530add x y = x + y</code></pre>
531 <pre><code class="haskell fragment">add 8 9
532-- 17</code></pre>
533 <pre><code class="haskell fragment">8 `add` 9
534-- 17</code></pre>
535 </section>
536 </section>
537 </section>
538 <section>
539 <section>
540 <h2>Список</h2>
541 </section>
542 <section>
543 <h3>Односвязный список</h3>
544 <pre><code class="haskell fragment">data IntList = Cons Int IntList | Nil</code></pre>
545 <pre><code class="haskell fragment">nums :: IntList
546nums = 1 `Cons` (2 `Cons` (3 `Cons` Nil))</code></pre>
547 <pre><code class="haskell fragment">sum :: IntList -> Int</code></pre>
548 <pre><code class="haskell fragment">sum (Cons x xs) = x + sum xs</code></pre>
549 <pre><code class="haskell fragment">sum Nil = 0
550sum (Cons x xs) = x + sum xs</code></pre>
551 <pre><code class="haskell fragment">sum nums
552-- 6</code></pre>
554 </section>
555 <section>
556 <pre><code class="haskell">take :: Int -> IntList -> IntList</code></pre>
557 <pre><code class="haskell fragment">take _ Nil = Nil
558take 0 _ = Nil
559take n (Cons x xs) = Cons x (take (n - 1) xs)</code></pre>
560 <pre><code class="haskell fragment">nums :: IntList
561nums = 1 `Cons` (2 `Cons` (3 `Cons` Nil))</code></pre>
562 <pre><code class="haskell fragment">take 2 nums
563-- Cons 1 (Cons 2 Nil)
564take 1029 nums
565-- Cons 1 (Cons 2 (Cons 3 Nil))
566take 0 nums
567-- Nil</code></pre>
569 </section>
570 <section>
571 <pre><code class="haskell">repeat :: Int -> IntList</code></pre>
572 <pre><code class="haskell fragment">repeat n = n : (repeat n)</code></pre>
573 <pre><code class="haskell fragment">repeat 8
574-- Cons 8 (Cons 8 (Cons 8 (Cons 8 (Cons 8 (Cons 8 (Cons 8 (Cons 8 (Cons 8 (Cons 8 (...</code></pre>
575 <pre><code class="haskell fragment">(take 3 . repeat) 8
576-- Cons 8 (Cons 8 (Cons 8 Nil))</code></pre>
577 <pre><code class="haskell fragment">(sum . take 3 . repeat) 8
578-- 24</code></pre>
579 </section>
580 <section>
581 <table>
582 <tr>
583 <td>Наша самодеятельность</td>
584 <td>В стандартной библиотеке</td>
585 </tr>
586 <tr class="fragment">
587 <td>
588 <pre><code class="haskell">IntList</code></pre>
589 </td>
590 <td>
591 <pre><code class="haskell">[Int]</code></pre>
592 </td>
593 </tr>
594 <tr class="fragment">
595 <td>
596 <pre><code class="haskell">Nil</code></pre>
597 </td>
598 <td>
599 <pre><code class="haskell">[]</code></pre>
600 </td>
601 </tr>
602 <tr class="fragment">
603 <td>
604 <pre><code class="haskell">Cons</code></pre>
605 </td>
606 <td>
607 <pre><code class="haskell">:</code></pre>
608 </td>
609 </tr>
610 <tr class="fragment">
611 <td>
612 <pre><code class="haskell">Cons 3 (Cons 4 Nil)</code></pre>
613 </td>
614 <td>
615 <pre class="fragment"><code class="haskell">3 : 4 : []</code></pre>
616 <pre class="fragment"><code class="haskell">[3, 4]</code></pre>
617 </td>
618 </tr>
619 </table>
620 </section>
621 <section>
622 <p data-markdown>`repeat`, `sum` и `take` тоже есть в стандартной библиотеке.</p>
623 </section>
624 </section>
625 <section>
626 <section>
627 <h2>QuickSort</h2>
628 </section>
629 <section>
630 <pre><code class="haskell">quicksort :: [Int] -> [Int]</code></pre>
632 <pre><code class="haskell fragment">quicksort (x:xs) =
633 quicksort smaller ++ [x] ++ quicksort larger
634 where
635 smaller = filter (< x) xs
636 larger = filter (>= x) xs</code></pre>
637 </section>
638 <section>
639 <pre><code class="haskell">filter :: (Bool -> Int) -> [Int] -> [Int]</code></pre>
640 <pre><code class="haskell fragment">filter f (x:xs) =
641 if f x
642 then filter f xs
643 else x:(filter f xs)</code></pre>
644 <pre><code class="haskell fragment">filter _ [] = []
645filter f (x:xs) =
646 if f x
647 then filter f xs
648 else x:(filter f xs)</code></pre>
649 </section>
650 <section>
651 <pre><code class="haskell">quicksort :: [Int] -> [Int]
652quicksort (x:xs) =
653 quicksort smaller ++ [x] ++ quicksort larger
654 where
655 smaller = filter (< x) xs
656 larger = filter (>= x) xs
657 filter _ [] = []
658 filter f (x:xs) =
659 if f x
660 then filter f xs
661 else x:(filter f xs)</code></pre>
662 </section>
663 <section>
664 <pre><code class="haskell">quicksort :: [Int] -> [Int]
665quicksort [] = []
666quicksort (x:xs) =
667 quicksort smaller ++ [x] ++ quicksort larger
668 where
669 smaller = filter (< x) xs
670 larger = filter (>= x) xs
671 filter _ [] = []
672 filter f (x:xs) =
673 if f x
674 then filter f xs
675 else x:(filter f xs)</code></pre>
676 <pre><code class="haskell fragment">quicksort [2, 1, 3, 4]
677-- [1, 2, 3, 4]</code></pre>
678 </section>
679 <section>
680 <p data-markdown>`filter` тоже есть в стандартной библиотеке.</p>
681 </section>
682 </section>
683 <section>
684 <section>
685 <h2>Где и как смотреть "стандартную библиотеку"</h2>
686 </section>
687 <section>
688 <ol>
689 <li>
690 <a href="https://hackage.haskell.org/package/base">Hackage</a>
692 <p data-markdown>
693 (Там вам нужен только пакет `base`. Ссылка ведет прямо на него.)
695 Еще если там нажать `s`, то будет поиск.
696 </p>
697 </li>
698 <li class="fragment">
699 <a href="https://hoogle.haskell.org">Hoogle</a>
701 <p data-markdown>
702 Это поиск по типам.
704 Например: `Int -> [Int] -> [Int]`
706 (Тут вам опять же нужен только пакет `base`. Нужно чтобы справа было "package:base".)
708 </p>
709 </li>
710 </ol>
711 </section>
712 </section>
713 </div>
714 </div>
716 <script src="./js/reveal.js"></script>
718 <script>
719 // More info about config & dependencies:
720 // - https://github.com/hakimel/reveal.js#configuration
721 // - https://github.com/hakimel/reveal.js#dependencies
722 Reveal.initialize({
724 // Displaнес presentation control arrows
725 controls: true,
727 // Help the user learn the controls by providing hints, for example by
728 // bouncing the down arrow when they first encounter a vertical slide
729 controlsTutorial: true,
731 // Determines where controls appear, "edges" or "bottom-right"
732 controlsLayout: 'bottom-right',
734 // Visibility rule for backwards navigation arrows; "faded", "hidden"
735 // or "visible"
736 controlsBackArrows: 'faded',
738 // Display a presentation progress bar
739 progress: true,
741 // Display the page number of the current slide
742 slideNumber: false,
744 // Add the current slide number to the URL hash so that reloading the
745 // page/copying the URL will return you to the same slide
746 hash: true,
748 // Push each slide change to the browser history. Implies `hash: true`
749 history: false,
751 // Enable keyboard shortcuts for navigation
752 keyboard: true,
754 // Enable the slide overview mode
755 overview: true,
757 // Vertical centering of slides
758 center: true,
760 // Enables touch navigation on devices with touch input
761 touch: true,
763 // Loop the presentation
764 loop: false,
766 // Change the presentation direction to be RTL
767 rtl: false,
769 // See https://github.com/hakimel/reveal.js/#navigation-mode
770 navigationMode: 'linear',
772 // Randomizes the order of slides each time the presentation loads
773 shuffle: false,
775 // Turns fragments on and off globally
776 fragments: true,
778 // Flags whether to include the current fragment in the URL,
779 // so that reloading brings you to the same fragment position
780 fragmentInURL: true,
782 // Flags if the presentation is running in an embedded mode,
783 // i.e. contained within a limited portion of the screen
784 embedded: false,
786 // Flags if we should show a help overlay when the questionmark
787 // key is pressed
788 help: true,
790 // Flags if speaker notes should be visible to all viewers
791 showNotes: false,
793 // Global override for autoplaying embedded media (video/audio/iframe)
794 // - null: Media will only autoplay if data-autoplay is present
795 // - true: All media will autoplay, regardless of individual setting
796 // - false: No media will autoplay, regardless of individual setting
797 autoPlayMedia: null,
799 // Global override for preloading lazy-loaded iframes
800 // - null: Iframes with data-src AND data-preload will be loaded when within
801 // the viewDistance, iframes with only data-src will be loaded when visible
802 // - true: All iframes with data-src will be loaded when within the viewDistance
803 // - false: All iframes with data-src will be loaded only when visible
804 preloadIframes: null,
806 // Number of milliseconds between automatically proceeding to the
807 // next slide, disabled when set to 0, this value can be overwritten
808 // by using a data-autoslide attribute on your slides
809 autoSlide: 0,
811 // Stop auto-sliding after user input
812 autoSlideStoppable: true,
814 // Use this method for navigation when auto-sliding
815 autoSlideMethod: Reveal.navigateNext,
817 // Specify the average time in seconds that you think you will spend
818 // presenting each slide. This is used to show a pacing timer in the
819 // speaker view
820 defaultTiming: 120,
822 // Enable slide navigation via mouse wheel
823 mouseWheel: false,
825 // Hide cursor if inactive
826 hideInactiveCursor: true,
828 // Time before the cursor is hidden (in ms)
829 hideCursorTime: 5000,
831 // Hides the address bar on mobile devices
832 hideAddressBar: true,
834 // Opens links in an iframe preview overlay
835 // Add `data-preview-link` and `data-preview-link="false"` to customise each link
836 // individually
837 previewLinks: false,
839 // Transition style
840 transition: 'slide', // none/fade/slide/convex/concave/zoom
842 // Transition speed
843 transitionSpeed: 'default', // default/fast/slow
845 // Transition style for full page slide backgrounds
846 backgroundTransition: 'fade', // none/fade/slide/convex/concave/zoom
848 // Number of slides away from the current that are visible
849 viewDistance: 3,
851 // Parallax background image
852 parallaxBackgroundImage: '', // e.g. "'https://s3.amazonaws.com/hakim-static/reveal-js/reveal-parallax-1.jpg'"
854 // Parallax background size
855 parallaxBackgroundSize: '', // CSS syntax, e.g. "2100px 900px"
857 // Number of pixels to move the parallax background per slide
858 // - Calculated automatically unless specified
859 // - Set to 0 to disable movement along an axis
860 parallaxBackgroundHorizontal: null,
861 parallaxBackgroundVertical: null,
863 // The display mode that will be used to show slides
864 display: 'block',
866 pdfSeparateFragments: false,
868 defaultTiming: null,
870 markdown: {
871 smartypants: true
872 },
875 dependencies: [
876 { src: './plugin/markdown/marked.js' },
877 { src: './plugin/markdown/markdown.js' },
878 { src: './plugin/zoom-js/zoom.js', async: true },
879 { src: './plugin/notes/notes.js', async: true },
880 { src: './plugin/highlight/highlight.js', async: true }
881 ]
883 });
884 </script>
885</body>
887</html>