Главная » Haskell » Импорт сторонних модулей

0

Вполне естественно, что оформленные таким образом модули в языке Haskell можно импортировать в другие модули для использования тех  программных сущностей, которые  экспортируются вовне  импортируемыми модулями. Это — главное предназначение  системы  модулей в любом языке  программирования. На это основано и построение библиотек, и повторное использование программных сущностей.

Импортирование сторонних модулей производится при помощи  ключевого слова import.  После этого ключевого слова должно располагаться  наименование импортируемого  модуля, после которого может находиться перечисление тех программных сущностей, которые импортируются в текущий модуль. В случае

если такого списка нет, в текущий модуль импортируются все программные сущности, которые экспортируются импортируемым модулем. Например:

import Data.List

import  Data.Char  ( toLower,

toUpper

)

import  Data.Tree  ( Tree

(

Node

)

)

Как  видно, при перечислении импортируемых программных сущностей действуют те же  самые правила, которые  используются  и при перечислении экспортируемых элементов. Для  импортируемых типов данных можно также  перечислять импортируемые конструкторы данных. При этом необходимо учесть, что множество импортируемых программных сущностей в любом случае должно быть подмножеством экспортируемых. В случае  если для импорта указана некоторая программная сущность, не  перечисленная в списке  экспортируемых в импортируемом модуле, возникнет ошибка.

Остаётся рассмотреть случай, когда в импортируемых модулях имеются программные сущности с одинаковыми идентификаторами. Как  поступать в такой ситуации? Для этих целей в языке Haskell можно использовать либо сокрытие программных сущностей при  импорте, либо квалификацию оных посредством имени модуля, в котором они описаны. Ниже рассматриваются эти методы.

Сокрытие  программных  сущностей при импорте модуля

Иногда бывает проще при импорте скрыть некоторые  программные сущности из импортируемого модуля, нежели перечислять огромный список тех, что импортируются. Это можно сделать при помощи ключевого слова hiding, которое должно располагаться после наименования модуля при импорте. После этого

слова опять же в круглых скобках () через запятую перечисляются идентификаторы тех программных сущностей, которые скрываются при импорте. Например:

import SomeModule  hiding ( someFunction

)

Само собой разумеется, что в этом случае можно скрывать только  те программные сущности, которые экспортируются импортируемым модулем. Во всяком случае при импорте нескольких модулей всегда необходимо добиваться ситуации, когда при импорте не происходит коллизии имён программных сущно стей — все коллизии должны быть разрешены при помощи сокрытия или квалификации (см. ниже).

Необходимо отметить, что подобным образом невозможно скрыть типы данных и синонимы типов. Если в нескольких импортируемых  модулях имеются типы с одинаковыми идентификаторами, то необходимо использовать квалификацию имён.

Квалифицированный  импорт модуля

Иногда в описанном выше случае, когда при импорте двух модулей получается коллизия имён программных сущностей, в проекте для работы необходимы обе сущности. Что делать? Вопрос несложный — язык Haskell предоставляет возможность использовать квалификацию идентификаторов при импорте. Это значит, что при использовании внешних (импортированных) программных сущностей их наименования при вызове должны префиксироваться идентификатором модуля.

Для этих целей необходимо  не просто импортировать заданный  модуль, но и указать, что модуль импортируется квалифицированно. Тогда все идентификаторы,  получаемые из этого модуля, должны  при  использовании квалифицироваться наименованием модуля. Это  достигается при помощи использования ключевого слова qualified:

import qualified  SomeModule

После такой директивы все программные сущности из модуля  SomeModule должны использоваться только с одноимённым префиксом, отделённым от идентификатора программной сущности точкой:

otherFunction data  = map  SomeModule.somefunction data

Такой подход позволяет избежать неопределённости в наименованиях. Однако после квалифицированного  импорта неквалифицированные идентификаторы импортированных программных сущностей уже использовать нельзя, даже если с такими идентификаторами нет никаких коллизий.

Единственная проблема, которая  возникает с квалификацией  идентификаторов из импортируемых модулей,  — использование точки в качестве операции композиции (.), которая определена в стандартном модуле Prelude.  Если квалифицированный идентификатор участвует в композиции функций, то транслятор языка Haskell может не понять, какая точка за что отвечает. В этом случае необходимо просто отделить операцию композиции (.) от своих аргументов пробелами.

Переименование модуля при квалифицированном импорте

Остаётся отметить такой аспект импортирования модулей, как переименование квалифицированного модуля. Иной раз разработчик программного обеспечения назовёт свой модуль слишком длинным наименованием, поэтому его использование в качестве префикса становится делом не только затруднительным, но и весьма сильно портящим исходные коды программ. Поэтому при импорте можно переименовать модуль, дав ему короткое название. Для этого используется ключевое слово as:

import qualified  AModuleWithAVeryLongName  as M

В      этом     случае     квалификация      идентификаторов     из      модуля AModuleWithAVeryLongName   должна   производиться  при    помощи   префикса M. Более того, при переименовании модулей не накладывается ограничения, которое запрещает разным модулям давать одинаковые имена. Если при импорте таких модулей не создаётся коллизий идентификаторов, то для разных модулей можно использовать одинаковые идентификаторы, введённые ключевым словом as. Однако это не очень хорошая практика, поскольку приводит к путанице.

Источник: Душкин Р. В., Справочник по языку Haskell. М.: ДМК Пресс, 2008. 544 с., ил.

По теме:

  • Комментарии