MyBooks.club
Все категории

Миран Липовача - Изучай Haskell во имя добра!

На сайте mybooks.club вы можете бесплатно читать книги онлайн без регистрации, включая Миран Липовача - Изучай Haskell во имя добра!. Жанр: Программирование издательство -,. Доступна полная версия книги с кратким содержанием для предварительного ознакомления, аннотацией (предисловием), рецензиями от других читателей и их экспертным мнением.
Кроме того, на сайте mybooks.club вы найдете множество новинок, которые стоит прочитать.

Название:
Изучай Haskell во имя добра!
Издательство:
-
ISBN:
-
Год:
-
Дата добавления:
17 сентябрь 2019
Количество просмотров:
700
Читать онлайн
Миран Липовача - Изучай Haskell во имя добра!

Миран Липовача - Изучай Haskell во имя добра! краткое содержание

Миран Липовача - Изучай Haskell во имя добра! - описание и краткое содержание, автор Миран Липовача, читайте бесплатно онлайн на сайте электронной библиотеки mybooks.club
На взгляд автора, сущность программирования заключается в решении проблем. Программист всегда думает о проблеме и возможных решениях – либо пишет код для выражения этих решений.Язык Haskell имеет множество впечатляющих возможностей, но главное его свойство в том, что меняется не только способ написания кода, но и сам способ размышления о проблемах и возможных решениях. Этим Haskell действительно отличается от большинства языков программирования. С его помощью мир можно представить и описать нестандартным образом. И поскольку Haskell предлагает совершенно новые способы размышления о проблемах, изучение этого языка может изменить и стиль программирования на всех прочих.Ещё одно необычное свойство Haskell состоит в том, что в этом языке придаётся особое значение рассуждениям о типах данных. Как следствие, вы помещаете больше внимания и меньше кода в ваши программы.Вне зависимости от того, в каком направлении вы намерены двигаться, путешествуя в мире программирования, небольшой заход в страну Haskell себя оправдает. А если вы решите там остаться, то наверняка найдёте чем заняться и чему поучиться!Эта книга поможет многим читателям найти свой путь к Haskell.Отображения, монады, моноиды и другое!Всё сказано в названии: «Изучай Хаскель во имя добра!» – весёлый иллюстрированный самоучитель по этому сложному функциональному языку.С помощью оригинальных рисунков автора, отсылке к поп-культуре, и, самое главное, благодаря полезным примерам кода, эта книга обучает основам функционального программирования так, как вы никогда не смогли бы себе представить.Вы начнете изучение с простого материала: основы синтаксиса, рекурсия, типы и классы типов. Затем, когда вы преуспеете в основах, начнется настоящий мастер-класс от профессионала: вы изучите, как использовать аппликативные функторы, монады, застежки, и другие легендарные конструкции Хаскеля, о которых вы читали только в сказках.Продираясь сквозь образные (и порой безумные) примеры автора, вы научитесь:• Смеяться в лицо побочным эффектам, поскольку вы овладеете техниками чистого функционального программирования.• Использовать волшебство «ленивости» Хаскеля для игры с бесконечными наборами данных.• Организовывать свои программы, создавая собственные типы, классы типов и модули.• Использовать элегантную систему ввода-вывода Хаскеля, чтобы делиться гениальностью ваших программ с окружающим миром.Нет лучшего способа изучить этот мощный язык, чем чтение «Изучай Хаскель во имя добра!», кроме, разве что, поедания мозга его создателей.Миран Липовача (Miran Lipovača) изучает информатику в Любляне (Словения). Помимо его любви к Хаскелю, ему нравится заниматься боксом, играть на бас-гитаре и, конечно же, рисовать. У него есть увлечение танцующими скелетами и числом 71, а когда он проходит через автоматические двери, он притворяется, что на самом деле открывает их силой своей мысли.

Изучай Haskell во имя добра! читать онлайн бесплатно

Изучай Haskell во имя добра! - читать книгу онлайн бесплатно, автор Миран Липовача

Каковы шансы появления каждой из этих букв? Если бы мы должны были изобразить просто четыре коробки, каждая из которых содержит вероятность, какими были бы эти вероятности? Чтобы узнать это, достаточно умножить каждую вероятность на все вероятности, которые в ней содержатся. Значение 'a' появилось бы один раз из восьми, как и 'b', потому что если мы умножим одну четвёртую на одну четвёртую, то получим одну восьмую. Значение 'c' появилось бы три раза из восьми, потому что три четвёртых, умноженные на одну вторую, – это три восьмых. Значение 'd' также появилось бы три раза из восьми. Если мы сложим все вероятности, они по-прежнему будут давать в сумме единицу.

Вот эта ситуация, выраженная в форме списка вероятностей:

thisSituation :: Prob (Prob Char)

thisSituation = Prob

   [(Prob [('a',1 % 2),('b',1 % 2)], 1 % 4)

   ,(Prob [('c',1 % 2),('d',1 % 2)], 3 % 4)

   ]

Обратите внимание, её тип – Prob (Prob Char). Поэтому теперь, когда мы поняли, как разгладить вложенный список вероятностей, всё, что нам нужно сделать, – написать для этого код. Затем мы можем определить операцию >>= просто как join (fmap f m), и заполучим монаду! Итак, вот функция flatten, которую мы будем использовать, потому что имя join уже занято:

flatten :: Prob (Prob a) –> Prob a

flatten (Prob xs) = Prob $ concat $ map multAll xs

   where multAll (Prob innerxs, p) = map ((x, r) –> (x, p*r)) innerxs

Функция multAll принимает кортеж, состоящий из списка вероятностей и вероятности p, которая к нему приложена, а затем умножает каждую внутреннюю вероятность на p, возвращая список пар элементов и вероятностей. Мы отображаем каждую пару в нашем списке вероятностей с помощью функции multAll, а затем просто разглаживаем результирующий вложенный список.

Теперь у нас есть всё, что нам нужно. Мы можем написать экземпляр класса Monad!

instance Monad Prob where

   return x = Prob [(x,1 % 1)]

   m >>= f = flatten (fmap f m)

   fail _ = Prob []

Поскольку мы уже сделали всю тяжелую работу, экземпляр очень прост. Мы определили функцию fail, которая такова же, как и для списков, поэтому если при сопоставлении с образцом в выражении do происходит неудача, неудача случается в контексте списка вероятностей.

Важно также проверить, что для только что созданной нами монады выполняются законы монад:

1. Первое правило говорит, что выражение return x >>= f должно равняться выражению f x. Точное доказательство было бы довольно громоздким, но нам видно, что если мы поместим значение в контекст по умолчанию с помощью функции return, затем отобразим это с помощью функции, используя fmap, а потом отобразим результирующий список вероятностей, то каждая вероятность, являющаяся результатом функции, была бы умножена на вероятность 1 % 1, которую мы создали с помощью функции return, так что это не повлияло бы на контекст.

2. Второе правило утверждает, что выражение m >> return ничем не отличается от m. Для нашего примера доказательство того, что выражение m >> return равно просто m, аналогично доказательству первого закона.

3. Третий закон утверждает, что выражение f <=< (g <=< h) должно быть аналогично выражению (f <=< g) <=< h. Это тоже верно, потому что данное правило выполняется для списковой монады, которая составляет основу для монады вероятностей, и потому что умножение ассоциативно. 1 % 2 * (1 % 3 * 1 % 5) равно (1 % 2 * 1 % 3) * 1 % 5.

Теперь, когда у нас есть монада, что мы можем с ней делать? Она может помочь нам выполнять вычисления с вероятностями. Мы можем обрабатывать вероятностные события как значения с контекстами, а монада вероятностей обеспечит отражение этих вероятностей в вероятностях окончательного результата.

Скажем, у нас есть две обычные монеты и одна монета, с одной стороны налитая свинцом: она поразительным образом выпадает на решку девять раз из десяти и на орла – лишь один раз из десяти. Если мы подбросим все монеты одновременно, какова вероятность того, что все они выпадут на решку? Во-первых, давайте создадим значения вероятностей для подбрасывания обычной монеты и для монеты, налитой свинцом:

data Coin = Heads | Tails deriving (Show, Eq)


coin :: Prob Coin

coin = Prob [(Heads,1 % 2),(Tails,1 % 2)]


loadedCoin :: Prob Coin

loadedCoin = Prob [(Heads,1 % 10),(Tails,9 % 10)]

И наконец, действие по подбрасыванию монет:

import Data.List (all)


flipThree :: Prob Bool

flipThree = do

   a <– coin

   b <– coin

   c <– loadedCoin

   return (all (==Tails) [a,b,c])

При попытке запустить его видно, что вероятность выпадения решки у всех трёх монет не так высока, даже несмотря на жульничество с нашей налитой свинцом монетой:

ghci> getProb flipThree

[(False,1 % 40),(False,9 % 40),(False,1 % 40),(False,9 % 40),

(False,1 % 40),(False,9 % 40),(False,1 % 40),(True,9 % 40)]

Все три приземлятся решкой вверх 9 раз из 40, что составляет менее 25%!.. Видно, что наша монада не знает, как соединить все исходы False, где все монеты не приземляются решкой вверх, в один исход. Впрочем, это не такая серьёзная проблема, поскольку написание функции для вставки всех одинаковых исходов в один исход довольно просто (это упражнение я оставляю вам в качестве домашнего задания).

В этом разделе мы перешли от вопроса («Что если бы списки также содержали информацию о вероятностях?») к созданию типа, распознанию монады и, наконец, созданию экземпляра и выполнению с ним некоторых действий. Думаю, это очаровательно! К этому времени у вас уже должно сложиться довольно неплохое понимание монад и их сути.

15

Застёжки

Хотя чистота языка Haskell даёт море преимуществ, вместе с тем он заставляет нас решать некоторые проблемы не так, как мы решали бы их в нечистых языках.



Из-за прозрачности ссылок одно значение в языке Haskell всё равно что другое, если оно представляет то же самое. Поэтому если у нас есть дерево, заполненное пятёрками (или, может, пятернями?), и мы хотим изменить одну из них на шестёрку, мы должны каким-то образом понимать, какую именно пятёрку в нашем дереве мы хотим изменить. Нам нужно знать, где в нашем дереве она находится. В нечистых языках можно было бы просто указать, где в памяти находится пятёрка, и изменить её. Но в языке Haskell одна пятёрка – всё равно что другая, поэтому нельзя проводить различие исходя из их расположения в памяти.

К тому же на самом деле мы не можем что-либо изменять. Когда мы говорим, что «изменяем дерево», то на самом деле имеем в виду, что мы берём дерево и возвращаем новое, аналогичное первоначальному, но немного отличающееся.

Одна вещь, которую мы можем сделать, – запомнить путь от корня дерева до элемента, который следует изменить. Мы могли бы сказать: «Возьми это дерево, пойди влево, пойди вправо, а затем опять влево и измени находящийся там элемент». Хотя это и работает, но может быть неэффективно. Если позднее мы захотим изменить элемент, находящийся рядом с элементом, изменённым нами ранее, нам снова нужно будет пройти весь путь от корня дерева до нашего элемента!

В этой главе вы увидите, как взять некую структуру данных и снабдить её тем, что называется застёжкой, чтобы фокусироваться на части структуры данных таким образом, который делает изменение её элементов простым, а прохождение по ней – эффективным. Славно!

Прогулка

Как вы узнали на уроках биологии, есть множество различных деревьев, поэтому давайте выберем зёрнышко, которое мы используем, чтобы посадить наше. Вот оно:

data Tree a = Empty | Node a (Tree a) (Tree a) deriving (Show)

Наше дерево или пусто, или является узлом, содержащим элемент и два поддерева. Вот хороший пример такого дерева, которое я отдаю вам, читатель, просто задаром!

freeTree :: Tree Char

freeTree =

  Node 'P'

    (Node 'O'

      (Node 'L'

        (Node 'N' Empty Empty)

        (Node 'T' Empty Empty)

      )

      (Node 'Y'

        (Node 'S' Empty Empty)

        (Node 'A' Empty Empty)

      )

    )

    (Node 'L'

      (Node 'W'

        (Node 'C' Empty Empty)

        (Node 'R' Empty Empty)

      )

      (Node 'A'

        (Node 'A' Empty Empty)

        (Node 'C' Empty Empty)

      )

    )

А вот это дерево, представленное графически:



Заметили символ W в дереве? Предположим, мы хотим заменить его символом P. Как нам это сделать? Ну, один из подходящих способов – сопоставление нашего дерева с образцом до тех пор, пока мы не найдём элемент, сначала двигаясь вправо, а затем влево. Вот соответствующий код:


Миран Липовача читать все книги автора по порядку

Миран Липовача - все книги автора в одном месте читать по порядку полные версии на сайте онлайн библиотеки mybooks.club.


Изучай Haskell во имя добра! отзывы

Отзывы читателей о книге Изучай Haskell во имя добра!, автор: Миран Липовача. Читайте комментарии и мнения людей о произведении.

Прокомментировать
Подтвердите что вы не робот:*
Подтвердите что вы не робот:*
Все материалы на сайте размещаются его пользователями.
Администратор сайта не несёт ответственности за действия пользователей сайта..
Вы можете направить вашу жалобу на почту librarybook.ru@gmail.com или заполнить форму обратной связи.