Основы функционального программирования/Haskell/Модули и монады: различия между версиями
Содержимое удалено Содержимое добавлено
м Множество правок |
м Замена Хаскель → Haskell |
||
Строка 5:
Языки программирования не обходятся без понятия [[w:модуль (программирование)|модуля]], разве что за исключением языков самого [[w:Низкоуровневый язык программирования|низкого уровня]], да и те последнее время обретают некоторые [[w:Высокоуровневый язык программирования|высокоуровневые]] свойства. Модули появились, когда [[w:программирование|программирование]] только зарождалось и возникла надобность разбивать программы на логические части, каждую из которых создавал бы отдельный разработчик или коллектив.
В этой лекции освещается, как в [[w:Haskell|
== Модули ==
В
Определить модуль просто: имя состоит из любых символов, лишь начинаться оно должно с прописной буквы. Имя модуля никак не связано с [[Файловая система|файловой системой]] (как, например, в [[w:Паскаль (язык программирования)|Паскале]] или [[w:Java|Java]]): файл, содержащий описание модуля, может называться отлично от самого модуля; также, он может содержать несколько модулей, ибо модуль есть лишь декларация самого высокого уровня.
На верхнем уровне модуля в
Определение модуля должно начинаться со служебного слова <code>module</code>. Ниже приведено определение модуля <code>Tree</code>:
Строка 38:
В приведенном примере видно, что модуль <code>Main</code> импортирует модуль <code>Tree</code>, причём в декларации <code>import</code> явно описано, какие именно объекты импортируются из модуля <code>Tree</code>. Если это описание опустить, то импортироваться будут все объекты, которые модуль экспортирует, то есть в данном случае можно было просто написать: <code>import Tree</code>.
В обычной практике один модуль импортирует несколько других, но при этом в импортируемых модулях есть объекты с одинаковым именем. Естественно, что в этом случае возникает конфликт имён. Чтобы этого избежать, в
<code>module Main where
Строка 50:
=== Абстрактные типы ===
В
<code>module TreeADT (Tree, leaf, branch, cell, left, right, isLeaf) where
Строка 69:
=== Другие аспекты использования модулей ===
Далее приводятся дополнительные аспекты системы модулей в
* В декларации импорта (<code>import</code>) можно выборочно спрятать некоторые из экспортируемых объектов служебным словом <code>hiding</code>. Это бывает полезным для явного исключения определений некоторых объектов из импортируемого модуля.
Строка 79:
== Монады ==
Многие новички в [[w:Функциональное программирование|функциональном програмировании]] бывают часто озадачены понятием монады в
Монады суть типы, представляющие собой экземпляры одного из следующих монадических классов: <code>Functor</code>, <code>Monad</code> и <code>MonadPlus</code>. Ни один из этих классов не может быть предком для другого класса, то есть монадические классы ненаследуемы. В модуле <code>Prelude</code> определены три монады: <code>IO</code>, <code>[]</code> и <code>Maybe</code>, то есть список также является монадой.
Строка 96:
Точное значение операция связывания конечно же зависит от конкретной реализации монады. Так, например, тип <code>IO</code> определяет операцию <code>(>>=)</code> как последовательное выполнение двух её операндов, а результат выполнения первого операнда последовательно передаётся во второй. Для двух других встроенных монадических типов (списки и <code>Maybe</code>) эта операция определена как передача нуля или более [[w:Параметр (программирование)|параметров]] из одного вычислительного процесса в следующий.
В
<code>do e1 ; e2 = e1 >> e2
Строка 167:
fail :: String -> m a</code>
Запись <code>m a</code> как бы показывает, что тип <code>a</code> (необходимо чётко помнить, что при определении классов и других типов данных символы типа <code>a</code>, <code>b</code> и так далее обозначают переменные типов) обрамлён монадическим типом <code>m</code>. Однако в реальности физическое обрамление доступно только для монадического типа «список», так как его обозначение в виде квадратных скобок пошло традиционно. В строгой нотации
2. Применение монад в функциональных языках — это по существу возвращение к императивности. Ведь операции связывания <code>(>>=)</code> и <code>(>>)</code> предполагают последовательное выполнение связанных выражений с передачей или без результатов вычисления. То есть монады — это императивное ядро внутри функциональных языков. С одной стороны, это идёт в разрез с теорией функционального програмирования, где отрицается понятие императивности, но, с другой стороны, некоторые задачи решаются только при помощи императивных принципов. И опять же,
|