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

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

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

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

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

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

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

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

foldl :: (a –> b –> a) –> a –> [b] –> a

Тогда как функция foldM имеет такой тип:

foldM :: (Monad m) => (a –> b –> m a) –> a –> [b] –> m a

Значение, которое возвращает бинарная функция, является монадическим, поэтому результат всей свёртки тоже является монадическим. Давайте сложим список чисел с использованием свёртки:

ghci> foldl (acc x –> acc + x) 0 [2,8,3,1]

14

Исходный аккумулятор равен 0, затем к аккумулятору прибавляется 2, что даёт в результате новый аккумулятор со значением 2. К этому аккумулятору прибавляется 8, что даёт в результате аккумулятор равный 10 и т. д. Когда мы доходим до конца, результатом является окончательный аккумулятор.

А ну как мы захотели бы сложить список чисел, но с дополнительным условием: если какое-то число в списке больше 9, всё должно окончиться неудачей? Имело бы смысл использовать бинарную функцию, которая проверяет, больше ли текущее число, чем 9. Если больше, то функция оканчивается неудачей; если не больше – продолжает свой радостный путь. Из-за этой добавленной возможности неудачи давайте заставим нашу бинарную функцию возвращать аккумулятор Maybe вместо обычного.

Вот бинарная функция:

binSmalls :: Int –> Int –> Maybe Int

binSmalls acc x

   | x > 9     = Nothing

   | otherwise = Just (acc + x)

Поскольку наша бинарная функция теперь является монадической, мы не можем использовать её с обычной функцией foldl; следует использовать функцию foldM. Приступим:

ghci> foldM binSmalls 0 [2,8,3,1]

Just 14

ghci> foldM binSmalls 0 [2,11,3,1]

Nothing

Клёво! Поскольку одно число в списке было больше 9, всё дало в результате значение Nothing. Свёртка с использованием бинарной функции, которая возвращает значение Writer, – тоже круто, потому что в таком случае вы журналируете что захотите по ходу работы вашей свёртки.

Создание безопасного калькулятора выражений в обратной польской записи

Решая задачу реализации калькулятора для обратной польской записи в главе 10, мы отметили, что он работал хорошо до тех пор, пока получаемые им входные данные имели смысл. Но если что-то шло не так, это приводило к аварийному отказу всей нашей программы. Теперь, когда мы знаем, как сделать уже существующий код монадическим, давайте возьмём наш калькулятор и добавим в него обработку ошибок, воспользовавшись монадой Maybe.



Мы реализовали наш калькулятор обратной польской записи, получая строку вроде "1 3 + 2 *" и разделяя её на слова, чтобы получить нечто подобное: ["1","3","+","2","*"]. Затем мы сворачивали этот список, начиная с пустого стека и используя бинарную функцию свёртки, которая добавляет числа в стек либо манипулирует числами на вершине стека, чтобы складывать их или делить и т. п.

Вот это было основным телом нашей функции:

import Data.List


solveRPN :: String –> Double

solveRPN = head . foldl foldingFunction [] . words

Мы превратили выражение в список строк и свернули его, используя нашу функцию свёртки. Затем, когда у нас в стеке остался лишь один элемент, мы вернули этот элемент в качестве ответа. Вот такой была функция свёртки:

foldingFunction :: [Double] –> String –> [Double]

foldingFunction (x:y:ys) "*" = (y * x):ys

foldingFunction (x:y:ys) "+" = (y + x):ys

foldingFunction (x:y:ys) "-" = (y - x):ys

foldingFunction xs numberString = read numberString:xs

Аккумулятором свёртки был стек, который мы представили списком значений типа Double. Если по мере того, как функция проходила по выражению в обратной польской записи, текущий элемент являлся оператором, она снимала два элемента с верхушки стека, применяла между ними оператор, а затем помещала результат обратно в стек. Если текущий элемент являлся строкой, представляющей число, она преобразовывала эту строку в фактическое число и возвращала новый стек, который был как прежний, только с этим числом, протолкнутым на верхушку.

Давайте сначала сделаем так, чтобы наша функция свёртки допускала мягкое окончание с неудачей. Её тип изменится с того, каким он является сейчас, на следующий:

foldingFunction :: [Double] –> String –> Maybe [Double]

Поэтому она либо вернёт новый стек в конструкторе Just, либо потерпит неудачу, вернув значение Nothing.

Функция reads похожа на функцию read, за исключением того, что она возвращает список с одним элементом в случае успешного чтения. Если ей не удалось что-либо прочитать, она возвращает пустой список. Помимо прочитанного ею значения она также возвращает ту часть строки, которую она не потребила. Мы сейчас скажем, что она должна потребить все входные данные для работы, и превратим её для удобства в функцию readMaybe. Вот она:

readMaybe :: (Read a) => String –> Maybe a

readMaybe st = case reads st of [(x, "")] –> Just x

                                _ –> Nothing

Теперь протестируем её:

ghci> readMaybe "1" :: Maybe Int

Just 1

ghci> readMaybe "ИДИ К ЧЁРТУ" :: Maybe Int

Nothing

Хорошо, кажется, работает. Итак, давайте превратим нашу функцию свёртки в монадическую функцию, которая может завершаться неудачей:

foldingFunction :: [Double] –> String –> Maybe [Double]

foldingFunction (x:y:ys) "*" = return ((y * x):ys)

foldingFunction (x:y:ys) "+" = return ((y + x):ys)

foldingFunction (x:y:ys) "-" = return ((y - x):ys)

foldingFunction xs numberString = liftM (:xs) (readMaybe numberString)

Первые три случая – такие же, как и прежние, только новый стек обёрнут в конструктор Just (для этого мы использовали здесь функцию return, но могли и просто написать Just). В последнем случае мы используем вызов readMaybe numberString, а затем отображаем это с помощью (:xs). Поэтому если стек равен [1.0,2.0], а выражение readMaybe numberString даёт в результате Just 3.0, то результатом будет [3.0,1.0,2.0]. Если же readMaybe numberString даёт в результате значение Nothing, результатом будет Nothing.

Давайте проверим функцию свёртки отдельно:

ghci> foldingFunction [3,2] "*"

Just [6.0]

ghci> foldingFunction [3,2] "-"

Just [-1.0]

ghci> foldingFunction [] "*"

Nothing

ghci> foldingFunction [] "1"

Just [1.0]

ghci> foldingFunction [] "1 уа-уа-уа-уа"

Nothing

Похоже, она работает! А теперь пришла пора для новой и улучшенной функции solveRPN. Вот она перед вами, дамы и господа!

import Data.List


solveRPN :: String –> Maybe Double

solveRPN st = do

   [result] <– foldM foldingFunction [] (words st)

   return result

Как и в предыдущей версии, мы берём строку и превращаем её в список слов. Затем производим свёртку, начиная с пустого стека, но вместо выполнения обычной свёртки с помощью функции foldl используем функцию foldM. Результатом этой свёртки с помощью функции foldM должно быть значение типа Maybe, содержащее список (то есть наш окончательный стек), и в этом списке должно быть только одно значение. Мы используем выражение do, чтобы взять это значение, и называем его result. В случае если функция foldM возвращает значение Nothing, всё будет равно Nothing, потому что так устроена монада Maybe. Обратите внимание на то, что мы производим сопоставление с образцом в выражении do, поэтому если список содержит более одного значения либо ни одного, сопоставление с образцом окончится неудачно и будет произведено значение Nothing. В последней строке мы просто вызываем выражение return result, чтобы представить результат вычисления выражения в обратной польской записи как результат окончательного значения типа Maybe.

Давайте попробуем:

ghci> solveRPN "1 2 * 4 +"

Just 6.0

ghci> solveRPN "1 2 * 4 + 5 *"

Just 30.0

ghci> solveRPN "1 2 * 4"

Nothing

ghci> solveRPN "1 8 трам-тарарам"

Nothing

Первая неудача возникает из-за того, что окончательный стек не является списком, содержащим один элемент: в выражении do сопоставление с образцом терпит фиаско. Вторая неудача возникает потому, что функция readMaybe возвращает значение Nothing.

Композиция монадических функций

Когда мы говорили о законах монад в главе 13, вы узнали, что функция <=< очень похожа на композицию, но вместо того чтобы работать с обычными функциями типа a –> b, она работает с монадическими функциями типа a –> m b. Вот пример:

ghci> let f = (+1) . (*100)

ghci> f 4

401

ghci> let g = (x –> return (x+1)) <=< (x –> return (x*100))

ghci> Just 4 >>= g

Just 401

В данном примере мы сначала произвели композицию двух обычных функций, применили результирующую функцию к 4, а затем произвели композицию двух монадических функций и передали результирующей функции Just 4 с использованием операции >>=.


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

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


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

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

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