Миран Липовача - Изучай Haskell во имя добра!
- Название:Изучай Haskell во имя добра!
- Автор:
- Жанр:
- Издательство:ДМК Пресс
- Год:2012
- Город:Москва
- ISBN:978-5-94074-749-9
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Миран Липовача - Изучай Haskell во имя добра! краткое содержание
Язык Haskell имеет множество впечатляющих возможностей, но главное его свойство в том, что меняется не только способ написания кода, но и сам способ размышления о проблемах и возможных решениях. Этим Haskell действительно отличается от большинства языков программирования. С его помощью мир можно представить и описать нестандартным образом. И поскольку Haskell предлагает совершенно новые способы размышления о проблемах, изучение этого языка может изменить и стиль программирования на всех прочих.
Ещё одно необычное свойство Haskell состоит в том, что в этом языке придаётся особое значение рассуждениям о типах данных. Как следствие, вы помещаете больше внимания и меньше кода в ваши программы.
Вне зависимости от того, в каком направлении вы намерены двигаться, путешествуя в мире программирования, небольшой заход в страну Haskell себя оправдает. А если вы решите там остаться, то наверняка найдёте чем заняться и чему поучиться!
Эта книга поможет многим читателям найти свой путь к Haskell.
Отображения, монады, моноиды и другое! Всё сказано в названии: «Изучай Хаскель во имя добра!» – весёлый иллюстрированный самоучитель по этому сложному функциональному языку.
С помощью оригинальных рисунков автора, отсылке к поп-культуре, и, самое главное, благодаря полезным примерам кода, эта книга обучает основам функционального программирования так, как вы никогда не смогли бы себе представить.
Вы начнете изучение с простого материала: основы синтаксиса, рекурсия, типы и классы типов. Затем, когда вы преуспеете в основах, начнется настоящий мастер-класс от профессионала: вы изучите, как использовать аппликативные функторы, монады, застежки, и другие легендарные конструкции Хаскеля, о которых вы читали только в сказках.
Продираясь сквозь образные (и порой безумные) примеры автора, вы научитесь:
• Смеяться в лицо побочным эффектам, поскольку вы овладеете техниками чистого функционального программирования.
• Использовать волшебство «ленивости» Хаскеля для игры с бесконечными наборами данных.
• Организовывать свои программы, создавая собственные типы, классы типов и модули.
• Использовать элегантную систему ввода-вывода Хаскеля, чтобы делиться гениальностью ваших программ с окружающим миром.
Нет лучшего способа изучить этот мощный язык, чем чтение «Изучай Хаскель во имя добра!», кроме, разве что, поедания мозга его создателей. Миран Липовача (Miran Lipovača) изучает информатику в Любляне (Словения). Помимо его любви к Хаскелю, ему нравится заниматься боксом, играть на бас-гитаре и, конечно же, рисовать. У него есть увлечение танцующими скелетами и числом 71, а когда он проходит через автоматические двери, он притворяется, что на самом деле открывает их силой своей мысли.
Изучай Haskell во имя добра! - читать онлайн бесплатно ознакомительный отрывок
Интервал:
Закладка:
Модуль Geometry
Давайте разберём процесс создания модулей на простом примере. Создадим модуль, который содержит функции для вычисления объёма и площади поверхности нескольких геометрических фигур. И начнём с создания файла Geometry.hs .
В начале модуля указывается его имя. Если мы назвали файл Geometry.hs , то имя нашего модуля должно быть Geometry
. Затем следует перечислить экспортируемые функции, после чего мы можем писать сами функции:
module Geometry
( sphereVolume
, sphereArea
, cubeVolume
, cubeArea
, cuboidArea
, cuboidVolume
) where
Как видите, мы будем вычислять площади и объёмы для сфер ( sphere
), кубов ( cube
) и прямоугольных параллелепипедов ( cuboid
). Сфера – это круглая штука наподобие грейпфрута, куб – квадратная штука, похожая на кубик Рубика, а прямоугольный параллелепипед – точь-в-точь пачка сигарет. (Дети, курить вредно!)
Продолжим и определим наши функции:
module Geometry
( sphereVolume , sphereArea
, cubeVolume
, cubeArea
, cuboidArea
, cuboidVolume
) where
sphereVolume :: Float –> Float
sphereVolume radius = (4.0 / 3.0) * pi * (radius 3)
sphereArea :: Float –> Float
sphereArea radius = 4 * pi * (radius 2)
cubeVolume :: Float –> Float
cubeVolume side = cuboidVolume side side side
cubeArea :: Float –> Float
cubeArea side = cuboidArea side side side
cuboidVolume :: Float –> Float –> Float –> Float
cuboidVolume a b c = rectArea a b * c
cuboidArea :: Float –> Float –> Float –> Float
cuboidArea a b c = rectArea a b * 2 + rectArea a c * 2 + rectArea c b * 2
rectArea :: Float –> Float –> Float
rectArea a b = a * b
Довольно стандартная геометрия, но есть несколько вещей, на которые стоит обратить внимание. Так как куб – это разновидность параллелепипеда, мы определили его площадь и объём, трактуя куб как параллелепипед с равными сторонами. Также мы определили вспомогательную функцию rectArea
, которая вычисляет площадь прямоугольника по его сторонам. Функция очень проста – она просто перемножает стороны. Заметьте, мы используем функцию rectArea
в функциях модуля (а именно в функциях cuboidArea
и cuboidVolume
), но не экспортируем её, так как хотим создать модуль для работы только с трёхмерными объектами.
При создании модуля мы обычно экспортируем только те функции, которые служат интерфейсом нашего модуля, и скрываем реализацию. Использующий наш модуль человек ничего не должен знать о тех функциях, которые мы не экспортируем. Мы можем полностью их поменять или удалить в следующей версии (скажем, удалить определение функции rectArea
и просто использовать умножение), и никто не будет против – в первую очередь потому, что эти функции не экспортируются.
Чтобы использовать наш модуль, запишем:
import Geometry
Файл Geometry.hs должен находиться в той же папке, что и импортирующая его программа.
Иерархия модулей
Модулям можно придать иерархическую структуру. Каждый модуль может иметь несколько подмодулей, которые в свою очередь также могут содержать подмодули. Давайте разделим наш модуль Geometry
таким образом, чтобы в него входили три подмодуля, по одному на каждый тип объекта.
Сначала создадим папку с именем Geometry . В этой папке мы разместим три файла: Sphere.hs , Cuboid.hs и Cube.hs . Посмотрим, что должно находиться в каждом файле.
Вот содержимое файла Sphere.hs :
module Geometry.Sphere
( volume
, area
) where
volume :: Float –> Float
volume radius = (4.0 / 3.0) * pi * (radius 3)
area :: Float –> Float
area radius = 4 * pi * (radius 2)
Файл Cuboid.hs выглядит так:
module Geometry.Cuboid
( volume
, area
) where
volume :: Float –> Float –> Float –> Float
volume a b c = rectArea a b * c
area :: Float –> Float –> Float –> Float
area a b c = rectArea a b * 2 + rectArea a c * 2 + rectArea c b * 2
rectArea :: Float –> Float –> Float
rectArea a b = a * b
А вот и содержимое файла Cube.hs :
module Geometry.Cube
( volume
, area
) where
import qualified Geometry.Cuboid as Cuboid
volume :: Float –> Float
volume side = Cuboid.volume side side side
area :: Float –> Float
area side = Cuboid.area side side side
Обратите внимание, что мы поместили файл Sphere.hs в папку с именем Geometry и определили имя модуля как Geometry.Sphere
. То же самое мы сделали для куба и параллелепипеда. Также отметьте, что во всех трёх модулях определены функции с одинаковыми именами. Мы вправе так поступать, потому что функции находятся в разных модулях.
Итак, если мы редактируем файл, который находится на одном уровне с папкой Geometry , то запишем:
import Geometry.Sphere
после чего сможем вызывать функции area
и volume
, которые вычислят площадь и объём сферы. Если нам потребуется использовать несколько наших модулей, мы должны выполнить квалифицированный импорт, потому что они экспортируют функции с одинаковыми именами. Делаем так:
import qualified Geometry.Sphere as Sphere
import qualified Geometry.Cuboid as Cuboid
import qualified Geometry.Cube as Cube
Затем мы сможем вызывать функции Sphere.area
, Sphere.volume
, Cuboid.area
и т. д., и каждая функция вычислит площадь или объём соответствующего объекта.
В следующий раз, когда вы поймаете себя за написанием огромного файла с кучей функций, попытайтесь выяснить, какие функции служат некоей общей цели, и можно ли включить их в отдельный модуль.
Позднее при написании программы со схожей функциональностью вы сможете просто импортировать свой модуль.
7
Создание новых типов и классов типов
В предыдущих главах мы изучили некоторые типы и классы типов в языке Haskell. Из этой главы вы узнаете, как создать и заставить работать свои собственные!
Введение в алгебраические типы данных

До сих пор мы сталкивались со многими типами данных – Bool
, Int
, Char
, Maybe
и др. Но как создать свой собственный тип? Один из способов – использовать ключевое слово data
. Давайте посмотрим, как в стандартной библиотеке определён тип Bool
:
data Bool = False | True
Ключевое слово data
объявляет новый тип данных. Часть до знака равенства вводит идентификатор типа, в данном случае Bool
. Часть после знака равенства – это конструкторы данных, которые также называют конструкторами значений. Они определяют, какие значения может принимать тип. Символ |
означает «или». Объявление можно прочесть так: тип Bool
может принимать значения True
или False
. И имя типа, и конструкторы данных должны начинаться с прописной буквы.
Рассуждая подобным образом, мы можем думать, что тип Int
объявлен так:
Интервал:
Закладка: