Основы функционального программирования/Haskell/Модули и монады: различия между версиями
Содержимое удалено Содержимое добавлено
м Шаблон со списком лекций |
Ramir (обсуждение | вклад) неполное форматирование. |
||
Строка 1:
{{ОФП Содержание}}
= Лекция 6. «Модули и монады в
Ни один язык программирования не обходится без понятия [[w:модуль (программирование)|модуля]], разве что только языки самого [[w:Низкоуровневый язык программирования|низкого уровня]], да и те в последнее время приобретают свойства языков более высокого уровня. Модули пришли из давнего прошлого, когда программирование
В
== Модули ==
В
Как известно, на верхнем уровне модуля в
Определение модуля должно начинаться со служебного слова module. Например, ниже приведено определение модуля Tree:
Строка 26:
fringe (Branch left right) = fringe left ++ fringe right
В этом модуле описан один тип (Tree — ничего страшного, что имя типа совпадает с названием модуля, в данном случае они находятся в различных пространствах имён) и одна функция (fringe).
Использование модуля в другом модуле выглядит еще проще:
Строка 36:
main = print (fringe (Branch (Leaf 1) (Leaf 2)))
В приведенном примере видно, что модуль Main импортирует модуль Tree, причём в декларации import явно описано, какие именно объекты импортируются из модуля Tree. Если это описание опустить, то импортироваться будут все объекты, которые модуль экспортирует,
Бывает так, что один модуль импортирует несколько других (надо заметить, что это обычная ситуация), но при этом в импортируемых модулях существуют объекты с одним и тем же именем. Естественно, что в этом случае возникает конфликт имён. Чтобы этого избежать в
module Main where
Строка 50:
=== Абстрактные типы данных ===
В
module TreeADT (Tree, leaf, branch, cell, left, right, isLeaf) where
Строка 65:
isLeaf _ = False
Видно, что к внутренностям типа Tree внешний пользователь (программист) может пробраться только
=== Другие аспекты использования модулей ===
Далее приводятся дополнительные аспекты системы модулей в
*В декларации импорта (import) можно выборочно спрятать некоторые из экспортируемых объектов
*При импорте можно определить псевдоним модуля для квалификации имен экспортируемых из него объектов. Для этого используется служебное слово as. Это может быть полезным для того укорачивания имен модулей.
*Все программы неявно импортируют модуль Prelude. Если сделать явный импорт этого модуля, то в его декларации возможно скрыть некоторые объекты, чтобы впоследствии их переопределить.
Строка 79:
== Монады ==
Многие новички в функциональном програмировании бывают часто озадачены понятием монады в
Монады
Математически монада определяется через набор правил, которые связывают операции, производимые над монадой. Эти правила дают интуитивное понимание того, как должна использоваться монада и какова ее внутренняя структура. Для конкретизации далее рассматривается класс Monad, в котором определены две базовые операции и одна функция:
Строка 96:
Точное значение операция связывания конечно же зависит от конкретной реализации монады. Так, например, тип IO определяет операцию (>>=) как последовательное выполнение двух её операндов, а результат выполнения первого операнда последовательно передается во второй. Для двух других встроенных монадических типов (списки и Maybe) эта операция определена как передача нуля или более параметров из одного вычислительного процесса в следующий.
В
do e1 ; e2 = e1 >> e2
|