Россия, Петерубрг, СПБ-ГПУ, 1998 |
Модули
5.3. Объявления импорта
Переводы:
Сущности, экспортируемые модулем, можно ввести в область видимости другого модуля посредством объявления import в начале модуля. В объявлении import указывается импортируемый модуль и необязательно задаются импортируемые сущности. Один модуль можно импортировать с помощью более чем одного объявления import. Импортированные имена служат в качестве объявлений верхнего уровня: их область видимости простирается над всем телом модуля, но может быть сокрыта локальными связываниями имен отличного от верхнего уровня.
Влияние многократных объявлений import строго кумулятивно: сущность находится в области видимости, если она импортирована посредством любого из объявлений import в модуле. Порядок объявлений импорта не существенен.
С точки зрения лексики, каждый из терминальных символов "as", "qualified" и "hiding" является varid (идентификатором-переменной), а не reservedid (зарезервированным-идентификатором). Они имеют специальное значение только в контексте объявления import ; их также можно использовать в качестве переменных.
5.3.1. Что такое импортирование
Какие точно сущности должны быть импортированы, можно задать одним из следующих трех способов:
- Импортируемые сущности можно задать явно, перечислив их в круглых скобках. Элементы списка имеют ту же форму, что элементы в списках экспорта, за исключением того, что нельзя использовать квалификаторы и нельзя использовать сущность 'module modid'. Когда форма (..) импорта используется для типа или класса, (..) ссылается на все конструкторы, методы или имена полей, экспортированные из модуля.
В списке должны быть указаны только сущности, экспортированные импортируемым модулем. Список может быть пуст, в этом случае ничто, кроме экземпляров, не будет импортировано.
- Сущности могут быть исключены посредством использования формы hiding(import1 , ... , importn ) , которая указывает, что все объекты, экспортированные названным модулем, должны быть импортированы, за исключением указанных в списке. Конструкторы данных можно указать непосредственно в списках hiding без использования в префиксе связанного с ним типа. Таким образом, в
import M hiding (C)
любой конструктор, класс, или тип, названный C, исключен. Напротив, используя C в списке импорта, вы укажете лишь класс или тип.
Будет ошибкой указать в списке hiding сущность, которая на самом деле не экспортируется импортируемым модулем.
- Наконец, если impspec пропущен, то все сущности, экспортируемые указанным модулем, будут импортированы.
5.3.2. Импортирование с использованием квалификаторов
Для каждой сущности, импортируемой в соответствии с правилами раздела "5.3.1" , расширяется окружение верхнего уровня. Если объявление импорта использует ключевое слово qualified, то только квалифицированное имя сущности вводится в область видимости. Если ключевое слово qualified опущено, то оба имени: квалифицированное и неквалифицированное имя сущности - вводятся в область видимости. В разделе "5.5.1" квалифицированные имена описаны более подробно.
Квалификатор импортированного имени является именем импортированного модуля или локальным синонимом, заданным с помощью инструкции as (раздел "5.3.3" ) в инструкции import. Следовательно, квалификатор необязательно является именем модуля, в котором первоначально была объявлена сущность.
Возможность исключить неквалифицированные имена позволяет программисту осуществлять полное управление пространством неквалифицированных имен: локально определенная сущность может совместно использовать то же имя, что и импортируемая сущность с квалифицированным именем:
module Ring where import qualified Prelude - Все имена из Prelude должны быть квалифицированными import List( nub ) l1 + l2 = l1 Prelude.++ l2 - Этот + отличается от + в Prelude l1 * l2 = nub (l1 + l2) - Эта * отличается от * в Prelude succ = (Prelude.+ 1)
5.3.3. Локальные синонимы
Импортированным модулям можно присвоить локальный синоним в модуле, который осуществляет импортирование, для этого используется инструкция as. Например, в
import qualified VeryLongModuleName as C
к импортированным сущностям можно обращаться, используя в качестве квалификатора 'C.' вместо 'VeryLongModuleName.'. Это также позволяет другому модулю быть замененным на VeryLongModuleName без изменения квалификаторов, используемых для импортированного модуля. Более чем один модуль в области видимости может использовать тот же самый квалификатор, при условии, что все имена по-прежнему могут быть однозначно разрешены. Например:
module M where import qualified Foo as A import qualified Baz as A x = A.f
Этот модуль является правильным только при условии, что и Foo, и Baz не экспортируют f.
Инструкцию as можно также использовать в инструкции import без qualified:
import Foo as A(f)
Это объявление вводит в область видимости f и A.f.
5.3.4. Примеры
Для того чтобы разъяснить вышеупомянутые правила импорта, предположим, что модуль A экспортирует x и y. Тогда эта таблица показывает, какие имена будут введены в область видимости с помощью заданного объявления импорта:
Во всех случаях все объявления экземпляров в области видимости в модуле A будут импортированы (раздел "5.4" ).