Миран Липовача - Изучай Haskell во имя добра!
- Название:Изучай Haskell во имя добра!
- Автор:
- Жанр:
- Издательство:ДМК Пресс
- Год:2012
- Город:Москва
- ISBN:978-5-94074-749-9
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Миран Липовача - Изучай Haskell во имя добра! краткое содержание
Язык Haskell имеет множество впечатляющих возможностей, но главное его свойство в том, что меняется не только способ написания кода, но и сам способ размышления о проблемах и возможных решениях. Этим Haskell действительно отличается от большинства языков программирования. С его помощью мир можно представить и описать нестандартным образом. И поскольку Haskell предлагает совершенно новые способы размышления о проблемах, изучение этого языка может изменить и стиль программирования на всех прочих.
Ещё одно необычное свойство Haskell состоит в том, что в этом языке придаётся особое значение рассуждениям о типах данных. Как следствие, вы помещаете больше внимания и меньше кода в ваши программы.
Вне зависимости от того, в каком направлении вы намерены двигаться, путешествуя в мире программирования, небольшой заход в страну Haskell себя оправдает. А если вы решите там остаться, то наверняка найдёте чем заняться и чему поучиться!
Эта книга поможет многим читателям найти свой путь к Haskell.
Отображения, монады, моноиды и другое! Всё сказано в названии: «Изучай Хаскель во имя добра!» – весёлый иллюстрированный самоучитель по этому сложному функциональному языку.
С помощью оригинальных рисунков автора, отсылке к поп-культуре, и, самое главное, благодаря полезным примерам кода, эта книга обучает основам функционального программирования так, как вы никогда не смогли бы себе представить.
Вы начнете изучение с простого материала: основы синтаксиса, рекурсия, типы и классы типов. Затем, когда вы преуспеете в основах, начнется настоящий мастер-класс от профессионала: вы изучите, как использовать аппликативные функторы, монады, застежки, и другие легендарные конструкции Хаскеля, о которых вы читали только в сказках.
Продираясь сквозь образные (и порой безумные) примеры автора, вы научитесь:
• Смеяться в лицо побочным эффектам, поскольку вы овладеете техниками чистого функционального программирования.
• Использовать волшебство «ленивости» Хаскеля для игры с бесконечными наборами данных.
• Организовывать свои программы, создавая собственные типы, классы типов и модули.
• Использовать элегантную систему ввода-вывода Хаскеля, чтобы делиться гениальностью ваших программ с окружающим миром.
Нет лучшего способа изучить этот мощный язык, чем чтение «Изучай Хаскель во имя добра!», кроме, разве что, поедания мозга его создателей. Миран Липовача (Miran Lipovača) изучает информатику в Любляне (Словения). Помимо его любви к Хаскелю, ему нравится заниматься боксом, играть на бас-гитаре и, конечно же, рисовать. У него есть увлечение танцующими скелетами и числом 71, а когда он проходит через автоматические двери, он притворяется, что на самом деле открывает их силой своей мысли.
Изучай Haskell во имя добра! - читать онлайн бесплатно ознакомительный отрывок
Интервал:
Закладка:
Функция sequence
обычно используется, если мы хотим пройтись по списку функциями print
или putStrLn
. Вызов map print [1,2,3,4]
не создаёт действия ввода-вывода – вместо этого создаётся список действий. Такой код на самом деле эквивалентен следующему:
[print 1, print 2, print 3, print 4]
Если мы хотим преобразовать список действий в действие, то необходимо воспользоваться функцией sequence
:
ghci> sequence $ map print [1,2,3,4]
1
2
3
4
[(),(),(),()]
Но что это за [(),(),(),()]
в конце вывода? При выполнении в GHCi действия ввода-вывода помимо самого действия выводится результат выполнения, но только если этот результат не есть ()
. Поэтому при выполнении в GHCi putStrLn "ха-ха"
просто выводится строка – результатом является ()
. Если же попробовать ввести getLine
, то помимо собственно ввода с клавиатуры будет выведено введённое значение – результатом является IO
String
.
Функция mapM
Поскольку применение функции, возвращающей действие ввода-вывода, к элементам списка и последующее выполнение всех полученных действий очень распространено, для этих целей были введены две вспомогательные функции – mapM
и mapM_
. Функция mapM
принимает функцию и список, применяет функцию к элементам списка, сводит элементы в одно действие ввода-вывода и выполняет их. Функция mapM_
работает так же, но отбрасывает результат действия ввода-вывода. Она используется, когда нам не важен результат комбинированного действия ввода-вывода.
ghci> mapM print [1,2,3]
1
2
3
[(),(),()]
ghci> mapM_ print [1,2,3]
1
2
3
Функция forever
Функция forever
принимает действие ввода-вывода – параметр и возвращает действие ввода-вывода – результат. Действие-результат будет повторять действие-параметр вечно. Эта функция входит в модуль Control.Monad
. Следующая программа будет бесконечно спрашивать у пользователя строку и возвращать её в верхнем регистре:
import Control.Monad
import Data.Char
main = forever $ do
putStr "Введите что-нибудь: "
l <���– getLine
putStrLn $ map toUpper l
Функция forM
Функция forM
(определена в модуле Control.Monad
) похожа на функцию mapM
, но её параметры поменяны местами. Первый параметр – это список, второй – это функция, которую надо применить к списку и затем свести действия из списка в одно действие. Для чего это придумано? Если творчески использовать лямбда-выражения и ключевое слово do
, можно проделывать такие фокусы:
import Control.Monad
main = do
colors <���– forM [1,2,3,4] (\a –> do
putStrLn $ "С каким цветом ассоциируется число "
++ show a ++ "?"
color <���– getLine
return color)
putStrLn "Цвета, ассоциирующиеся с 1, 2, 3 и 4: "
mapM putStrLn colors
Вот что мы получим при запуске:
С каким цветом ассоциируется число 1?
белый
С каким цветом ассоциируется число 2?
синий
С каким цветом ассоциируется число 3?
красный
С каким цветом ассоциируется число 4?
оранжевый
Цвета, ассоциирующиеся с 1, 2, 3 и 4:
белый
синий
красный
оранжевый
Анонимная функция ( \a –> do ...
) – это функция, которая принимает число и возвращает действие ввода-вывода. Нам пришлось поместить её в скобки, иначе анонимная функция решит, что следующие два действия ввода-вывода принадлежат ей. Обратите внимание, что мы производим вызов return color
внутри блока do
. Это делается для того, чтобы действие ввода-вывода, возвращаемое блоком do
, содержало в себе цвет. На самом деле мы не обязаны этого делать, потому что функция getLine
уже содержит цвет внутри себя. Выполняя color <���– getLine
и затем return color
, мы распаковываем результат getLine
и затем запаковываем его обратно, то есть это то же самое, что просто вызвать функцию getLine
. Функция forM
(вызываемая с двумя параметрами) создаёт действие ввода-вывода, результат которого мы связываем с идентификатором colors
. Этот идентификатор – обычный список, содержащий строки. В конце мы распечатываем все цвета, вызывая выражение mapM putStrLn colors
.
Вы можете думать, что функция forM
имеет следующий смысл: «Создай действие ввода-вывода для каждого элемента в списке. Каков будет результат каждого такого действия, может зависеть от элемента, из которого оно создаётся. После создания списка действий исполни их и привяжи их результаты к чему-либо». Однако мы не обязаны их связывать – результаты можно просто отбросить.
На самом деле мы могли бы сделать это без использования функции forM
, но так легче читается. Обычно эта функция используется, когда нам нужно отобразить (map)
и объединить (sequence)
действия, которые мы тут же определяем в секции do
. Таким образом, мы могли бы заменить последнюю строку на выражение forM
colors
putStrLn
.
Обзор системы ввода-вывода
В этой главе мы изучили основы системы ввода-вывода языка Haskell. Также мы узнали, что такое действия ввода-вывода, как они позволяют выполнять ввод-вывод, в какой момент они выполняются. Итак, повторим пройденное: действия ввода-вывода – это значения, такие же, как любые другие в языке Haskell. Мы можем передать их в функции как параметры, функции могут возвращать действия ввода-вывода в качестве результата. Они отличаются тем, что если они попадут в функцию main
(или их введут в интерпретаторе GHCi), то будут выполнены. В этот момент они могут выводить что-либо на экран или управлять звуковыводящим устройством. Каждое действие ввода-вывода может содержать результат общения с реальным миром.
Не думайте о функции, например о putStrLn
, как о функции, которая принимает строку и печатает её на экране. Думайте о ней как о функции, которая принимает строку и возвращает действие ввода-вывода. Это действие при выполнении печатает нечто ценное на вашем терминале.
9
Больше ввода и вывода
Теперь, когда вы понимаете идеи, лежащие в основе ввода-вывода в языке Haskell, можно приступать к интересным штукам. В этой главе мы будем обрабатывать файлы, генерировать случайные числа, читать аргументы командной строки и много чего ещё. Будьте готовы!
Файлы и потоки
Вооружившись знанием того, как работают действия ввода-вывода, можно перейти к чтению и записи файлов. Но прежде давайте посмотрим, как Haskell умеет работать с потоками данных. Потоком называется последовательность фрагментов данных, которые поступают на вход программы и выводятся в результате её работы. Например, когда вы вводите в программу символы, печатая их на клавиатуре, последовательность этих символов может рассматриваться как поток.
Читать дальшеИнтервал:
Закладка: