Миран Липовача - Изучай Haskell во имя добра!
- Название:Изучай Haskell во имя добра!
- Автор:
- Жанр:
- Издательство:ДМК Пресс
- Год:2012
- Город:Москва
- ISBN:978-5-94074-749-9
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Миран Липовача - Изучай Haskell во имя добра! краткое содержание
Язык Haskell имеет множество впечатляющих возможностей, но главное его свойство в том, что меняется не только способ написания кода, но и сам способ размышления о проблемах и возможных решениях. Этим Haskell действительно отличается от большинства языков программирования. С его помощью мир можно представить и описать нестандартным образом. И поскольку Haskell предлагает совершенно новые способы размышления о проблемах, изучение этого языка может изменить и стиль программирования на всех прочих.
Ещё одно необычное свойство Haskell состоит в том, что в этом языке придаётся особое значение рассуждениям о типах данных. Как следствие, вы помещаете больше внимания и меньше кода в ваши программы.
Вне зависимости от того, в каком направлении вы намерены двигаться, путешествуя в мире программирования, небольшой заход в страну Haskell себя оправдает. А если вы решите там остаться, то наверняка найдёте чем заняться и чему поучиться!
Эта книга поможет многим читателям найти свой путь к Haskell.
Отображения, монады, моноиды и другое! Всё сказано в названии: «Изучай Хаскель во имя добра!» – весёлый иллюстрированный самоучитель по этому сложному функциональному языку.
С помощью оригинальных рисунков автора, отсылке к поп-культуре, и, самое главное, благодаря полезным примерам кода, эта книга обучает основам функционального программирования так, как вы никогда не смогли бы себе представить.
Вы начнете изучение с простого материала: основы синтаксиса, рекурсия, типы и классы типов. Затем, когда вы преуспеете в основах, начнется настоящий мастер-класс от профессионала: вы изучите, как использовать аппликативные функторы, монады, застежки, и другие легендарные конструкции Хаскеля, о которых вы читали только в сказках.
Продираясь сквозь образные (и порой безумные) примеры автора, вы научитесь:
• Смеяться в лицо побочным эффектам, поскольку вы овладеете техниками чистого функционального программирования.
• Использовать волшебство «ленивости» Хаскеля для игры с бесконечными наборами данных.
• Организовывать свои программы, создавая собственные типы, классы типов и модули.
• Использовать элегантную систему ввода-вывода Хаскеля, чтобы делиться гениальностью ваших программ с окружающим миром.
Нет лучшего способа изучить этот мощный язык, чем чтение «Изучай Хаскель во имя добра!», кроме, разве что, поедания мозга его создателей. Миран Липовача (Miran Lipovača) изучает информатику в Любляне (Словения). Помимо его любви к Хаскелю, ему нравится заниматься боксом, играть на бас-гитаре и, конечно же, рисовать. У него есть увлечение танцующими скелетами и числом 71, а когда он проходит через автоматические двери, он притворяется, что на самом деле открывает их силой своей мысли.
Изучай Haskell во имя добра! - читать онлайн бесплатно ознакомительный отрывок
Интервал:
Закладка:
Ранее в этой главе мы решали задачу, в которой требовалось найти сумму всех нечётных квадратов меньших 10 000. Вот как будет выглядеть решение, если мы поместим его в функцию:
oddSquareSum :: Integer
oddSquareSum = sum (takeWhile (<10000) (filter odd (map ( 2) [1..])))
Со знанием композиции функций этот код можно переписать так:
oddSquareSum :: Integer
oddSquareSum = sum . takeWhile (<10000) . filter odd $ map ( 2) [1..]
Всё это на первый взгляд может показаться странным, но вы быстро привыкнете. В подобных записях меньше визуального «шума», поскольку мы убрали все скобки. При чтении такого кода можно сразу сказать, что filter odd
применяется к результату map ( 2) [1..]
, что затем применяется takeWhile (<10000)
, а функция sum
суммирует всё, что получилось в результате.
6
Модули

В языке Haskell модуль – это набор взаимосвязанных функций, типов и классов типов. Программа на Haskell – это набор модулей; главный модуль подгружает все остальные и использует функции, определённые в них, чтобы что-либо сделать. Разбиение кода на несколько модулей удобно по многим причинам. Если модуль достаточно общий, экспортируемые им функции могут быть использованы во множестве программ. Если ваш код разделён на несколько самостоятельных модулей, не очень зависящих один от другого (мы говорим, что они слабо связаны), модули могут многократно использоваться в разных проектах. Это отчасти облегчает непростую задачу написания кода, разбивая его на несколько частей, каждая из которых имеет некоторое назначение.
Стандартная библиотека языка Haskell разбита на модули, каждый из которых содержит взаимосвязанные функции и типы, служащие некоторой общей цели. Есть модуль для работы со списками, модуль для параллельного программирования, модуль для работы с комплексными числами и т. д. Все функции, типы и классы типов, с которыми мы имели дело до сих пор, были частью стандартного модуля Prelude
– он импортируется по умолчанию. В этой главе мы познакомимся с несколькими полезными модулями и их функциями. Но для начала посмотрим, как импортировать модули.
Импорт модулей
Синтаксис для импорта модулей в программах на языке Haskell – import ModuleName
. Импортировать модули надо прежде, чем вы приступите к определению функций, поэтому обычно импорт делается в начале файла. Конечно же, одна программа может импортировать несколько модулей. Для этого вынесите каждый оператор import
в отдельную строку.
Давайте импортируем модуль Data.List
, который содержит массу функций для работы со списками, и используем экспортируемую им функцию для того, чтобы написать свою – вычисляющую, сколько уникальных элементов содержит список.
import Data.List
numUniques :: (Eq a) => [a] –> Int
numUniques = length . nub
Когда выполняется инструкция import Data.List
, все функции, экспортируемые модулем Data.List
, становятся доступными в глобальном пространстве имён. Это означает, что вы можете вызывать их из любого места программы. Функция nub
определена в модуле Data.List
; она принимает список и возвращает список, из которого удалены дубликаты элементов исходного списка. Композиция функций length
и nub
создаёт функцию, которая эквивалентна \xs –> length (nub xs)
.
ПРИМЕЧАНИЕ.Чтобы найти нужные функции и уточнить, где они определены, воспользуйтесь сервисом Hoogle, который доступен по адресу http://www.haskell.org/hoogle/. Это поистине удивительный поисковый механизм для языка Haskell, который позволяет вести поиск по имени функции, по имени модуля и даже по сигнатуре.
В интерпретаторе GHCi вы также можете подключить функции из модулей к глобальному пространству имён. Если вы работаете в GHCi и хотите вызывать функции, экспортируемые модулем Data.List
, напишите следующее:
ghci> :m + Data.List
Если требуется подгрузить программные сущности из нескольких модулей, не надо вызывать команду :m +
несколько раз, так как можно загрузить ряд модулей одновременно:
ghci> :m + Data.List Data.Map Data.Set
Кроме того, если вы загрузили скрипт, который импортирует модули, то не нужно использовать команду :m +
, чтобы получить к ним доступ.
Если вам необходимо всего несколько функций из модуля, вы можете выборочно импортировать только эти функции. Если бы вам были нужны только функции nub
и sort
из модуля Data.List
, импорт выглядел бы так:
import Data.List (nub, sort)
Также вы можете осуществить импорт всех функций из модуля за исключением некоторых. Это бывает полезно, когда несколько модулей экспортируют функции с одинаковыми именами, и вы хотите избавиться от ненужных повторов. Предположим, у вас уже есть функция с именем nub
и вы хотите импортировать все функции из модуля Data.List
, кроме nub
, определённой в нём:
import Data.List hiding (nub)
Другой способ разрешения конфликтов имён – квалифицированный импорт. Модуль Data.Map
, который содержит структуру данных для поиска значения по ключу, экспортирует несколько функций с теми же именами, что и модуль Prelude
, например filter
и null
. Если мы импортируем модуль Data.Map
и вызовем функцию filter
, язык Haskell не будет знать, какую функцию использовать. Вот как можно обойти такую ситуацию:
import qualified Data.Map
Если после такого импорта нам понадобится функция filter
из модуля Data.Map
; мы должны вызывать её как Data.Map.filter
– просто идентификатор filter
ссылается на обычную функцию из модуля Prelude
, которую мы все знаем и любим. Но печатать строку Data.Map
перед именем каждой функции может и поднадоесть! Вот почему желательно переименовать модуль при импорте во что-нибудь более короткое:
import qualified Data.Map as M
Теперь, чтобы сослаться на функцию из Data.Map
, мы вызываем её как M.filter
.
Как вы видите, символ .
используется для обращения к функциям, импортированным из модулей с указанием квалификатора, например: M.filter
. Мы также помним, что он используется для обозначения композиции функций. Как Haskell узнаёт, что мы имеем в виду? Если мы помещаем символ .
между квалифицированным именем модуля и функцией без пробелов – это обращение к функции из модуля; во всех остальных случаях – композиция функций.
ПРИМЕЧАНИЕ.Отличный способ узнать Haskell изнутри – просмотреть документацию к стандартной библиотеке и исследовать все стандартные модули и их функции. Также можно изучить исходные тексты всех модулей. Чтение исходных текстов некоторых модулей – отличный способ освоить язык и прочувствовать его особенности [9] В тех же целях издательством «ДМК Пресс» выпущена книга: Душкин Р. В. Справочник по языку Haskell . – М.: ДМК Пресс, 2008. – 544 стр., ил. ISBN 5–94074–410–9.
.
Интервал:
Закладка: