Миран Липовача - Изучай Haskell во имя добра!
- Название:Изучай Haskell во имя добра!
- Автор:
- Жанр:
- Издательство:ДМК Пресс
- Год:2012
- Город:Москва
- ISBN:978-5-94074-749-9
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Миран Липовача - Изучай Haskell во имя добра! краткое содержание
Язык Haskell имеет множество впечатляющих возможностей, но главное его свойство в том, что меняется не только способ написания кода, но и сам способ размышления о проблемах и возможных решениях. Этим Haskell действительно отличается от большинства языков программирования. С его помощью мир можно представить и описать нестандартным образом. И поскольку Haskell предлагает совершенно новые способы размышления о проблемах, изучение этого языка может изменить и стиль программирования на всех прочих.
Ещё одно необычное свойство Haskell состоит в том, что в этом языке придаётся особое значение рассуждениям о типах данных. Как следствие, вы помещаете больше внимания и меньше кода в ваши программы.
Вне зависимости от того, в каком направлении вы намерены двигаться, путешествуя в мире программирования, небольшой заход в страну Haskell себя оправдает. А если вы решите там остаться, то наверняка найдёте чем заняться и чему поучиться!
Эта книга поможет многим читателям найти свой путь к Haskell.
Отображения, монады, моноиды и другое! Всё сказано в названии: «Изучай Хаскель во имя добра!» – весёлый иллюстрированный самоучитель по этому сложному функциональному языку.
С помощью оригинальных рисунков автора, отсылке к поп-культуре, и, самое главное, благодаря полезным примерам кода, эта книга обучает основам функционального программирования так, как вы никогда не смогли бы себе представить.
Вы начнете изучение с простого материала: основы синтаксиса, рекурсия, типы и классы типов. Затем, когда вы преуспеете в основах, начнется настоящий мастер-класс от профессионала: вы изучите, как использовать аппликативные функторы, монады, застежки, и другие легендарные конструкции Хаскеля, о которых вы читали только в сказках.
Продираясь сквозь образные (и порой безумные) примеры автора, вы научитесь:
• Смеяться в лицо побочным эффектам, поскольку вы овладеете техниками чистого функционального программирования.
• Использовать волшебство «ленивости» Хаскеля для игры с бесконечными наборами данных.
• Организовывать свои программы, создавая собственные типы, классы типов и модули.
• Использовать элегантную систему ввода-вывода Хаскеля, чтобы делиться гениальностью ваших программ с окружающим миром.
Нет лучшего способа изучить этот мощный язык, чем чтение «Изучай Хаскель во имя добра!», кроме, разве что, поедания мозга его создателей. Миран Липовача (Miran Lipovača) изучает информатику в Любляне (Словения). Помимо его любви к Хаскелю, ему нравится заниматься боксом, играть на бас-гитаре и, конечно же, рисовать. У него есть увлечение танцующими скелетами и числом 71, а когда он проходит через автоматические двери, он притворяется, что на самом деле открывает их силой своей мысли.
Изучай Haskell во имя добра! - читать онлайн бесплатно ознакомительный отрывок
Интервал:
Закладка:
applyMaybe :: Maybe a –> (a –> Maybe b) –> Maybe b
applyMaybe Nothing f = Nothing
applyMaybe (Just x) f = f x
Теперь давайте с ней поиграем. Мы будем использовать её как инфиксную функцию так, чтобы значение типа Maybe
было слева, а функция была справа:
ghci> Just 3 `applyMaybe` \x –> Just (x+1)
Just 4
ghci> Just "смайлик" `applyMaybe` \x –> Just (x ++ " :)")
Just "смайлик :)"
ghci> Nothing `applyMaybe` \x –> Just (x+1)
Nothing
ghci> Nothing `applyMaybe` \x –> Just (x ++ " :)")
Nothing
В данном примере, когда мы использовали функцию applyMaybe
со значением Just
и функцией, функция просто применялась к значению внутри конструктора Just
. Когда мы попытались использовать её со значением Nothing
, весь результат был равен Nothing
. Что насчёт того, если функция возвращает Nothing
? Давайте посмотрим:
ghci>Just 3 `applyMaybe` \x –> if x > 2 then Just x else Nothing
Just 3
ghci> Just 1 `applyMaybe` \x –> if x > 2 then Just x else Nothing
Nothing
Результаты оказались такими, каких мы и ждали! Если монадическое значение слева равно Nothing
, то всё будет равно Nothing
. А если функция справа возвращает значение Nothing
, результатом опять будет Nothing
. Это очень похоже на тот случай, когда мы использовали тип Maybe
в качестве аппликативного функтора и в результате получали значение Nothing
, если где-то в составе присутствовало значение Nothing
.
Похоже, мы догадались, как взять причудливое значение, передать его функции, которая принимает обычное значение, и вернуть причудливое значение. Мы сделали это, помня, что значение типа Maybe
представляет вычисление, которое могло окончиться неуспешно.
Вы можете спросить себя: «Чем это полезно?» Может показаться, что аппликативные функторы сильнее монад, поскольку аппликативные функторы позволяют нам взять обычную функцию и заставить её работать со значениями, имеющими контекст. В этой главе вы увидите, что монады, будучи усовершенствованными аппликативными функторами, тоже способны на такое. На самом деле они могут делать и кое-какие другие крутые вещи, на которые не способны аппликативные функторы.
Мы вернёмся к Maybe
через минуту, но сначала давайте взглянем на класс типов, который относится к монадам.
Класс типов Monad
Как и функторы, у которых есть класс типов Functor
, и аппликативные функторы, у которых есть класс типов Applicative
, монады обладают своим классом типов: Monad
! (Ух ты, кто бы мог подумать?)
class Monad m where
return :: a –> m a
(>>=) :: m a –> (a –> m b) –> m b
(>>) :: m a –> m b –> m b
x >> y = x >>= \_ –> y
fail :: String –> m a
fail msg = error msg
В первой строке говорится class Monad m where
. Стойте, не говорил ли я, что монады являются просто расширенными аппликативными функторами? Не надлежит ли здесь быть ограничению класса наподобие class (Applicative m) => Monad m where
, чтобы тип должен был являться аппликативным функтором, прежде чем он может быть сделан монадой? Ладно, положим, надлежит, – но когда появился язык Haskell, людям не пришло в голову, что аппликативные функторы хорошо подходят для этого языка. Тем не менее будьте уверены: каждая монада является аппликативным функтором, даже если в объявлении класса Monad
этого не говорится.

Первой функцией, которая объявлена в классе типов Monad
, является return
. Она аналогична функции pure
, находящейся в классе типов Applicative
. Так что, хоть она и называется по-другому, вы уже фактически с ней знакомы. Функция return
имеет тип (Monad m) => a –> m a
. Она принимает значение и помещает его в минимальный контекст по умолчанию, который по-прежнему содержит это значение. Другими словами, она принимает нечто и оборачивает это в монаду. Мы уже использовали функцию return
при обработке действий ввода-вывода (см. главу 8). Там она понадобилась для получения значения и создания фальшивого действия ввода-вывода, которое ничего не делает, а только возвращает это значение. В случае с типом Maybe
она принимает значение и оборачивает его в конструктор Just
.
ПРИМЕЧАНИЕ.Функция return
ничем не похожа на оператор return
из других языков программирования, таких как C++ или Java. Она не завершает выполнение функции. Она просто принимает обычное значение и помещает его в контекст.
Следующей функцией является >>=
, или связывание. Она похожа на применение функции, но вместо того, чтобы получать обычное значение и передавать его обычной функции, она принимает монадическое значение (то есть значение с контекстом) и передаёт его функции, которая принимает обычное значение, но возвращает монадическое.

Затем у нас есть операция >>
. Мы пока не будем обращать на неё большого внимания, потому что она идёт в реализации по умолчанию, и её редко реализуют при создании экземпляров класса Monad
. Мы подробно рассмотрим её в разделе «Банан на канате».
Последним методом в классе типов Monad
является функция fail
. Мы никогда не используем её в нашем коде явно. Вместо этого её использует язык Haskell, чтобы сделать возможным неуспешное окончание вычислений в специальной синтаксической конструкции для монад, с которой вы встретитесь позже. Нам не нужно сейчас сильно беспокоиться по поводу этой функции.
Теперь, когда вы знаете, как выглядит класс типов Monad
, давайте посмотрим, каким образом для типа Maybe
реализован экземпляр этого класса!
instance Monad Maybe where
return x = Just x
Nothing >>= f = Nothing
Just x >>= f = f x
fail _ = Nothing
Функция return
аналогична функции pure
, так что для работы с ней не нужно большого ума. Мы делаем то же, что мы делали в классе типов Applicative
, и оборачиваем в конструктор Just
. Операция >>=
аналогична нашей функции applyMaybe
. Когда мы передаём значение типа Maybe a
нашей функции, то запоминаем контекст и возвращаем значение Nothing
, если значением слева является Nothing
. Ещё раз: если значение отсутствует, нет способа применить к нему функцию. Если это значение Just
, мы берём то, что находится внутри, и применяем к этому функцию f
.
Мы можем поиграть с типом Maybe
как с монадой:
ghci> return "ЧТО" :: Maybe String
Just "ЧТО"
ghci> Just 9 >>= \x –> return (x*10)
Just 90
ghci> Nothing >>= \x –> return (x*10)
Nothing
В первой строке нет ничего нового или захватывающего, поскольку мы уже использовали функцию pure
с типом Maybe
, и мы знаем, что функция return
– это просто функция pure
под другим именем.
Интервал:
Закладка: