GHC отказывается экспортировать квалифицированные модули
Я хочу написать модуль, который реэкспортирует некоторый модуль, который он импортировал. Что-то вроде этого:
module Foo.A
( module Foo.B
, module Foo.C
) where
import qualified Foo.B
import qualified Foo.C
-- bunch of code using Foo.B and Foo.C here
Похоже, он должен работать; однако GHC печатает предупреждения об экспорте:
Foo/A.hs:2:5:
Warning: the export item `module Foo.B' exports nothing
Foo/A.hs:3:5:
Warning: the export item `module Foo.C' exports nothing
И GHCI отказывается загружать с них экспорт.
Я могу решить это, сделав импорт неквалифицированным, но тогда конфликты имен будут возникать между этими импортами и основным кодом модуля.
Есть ли способ заставить GHC экспортировать эти модули?
Ответы
Ответ 1
Нет, это не просто ограничение GHC, это способ импорта
и экспорт предназначен для работы в Haskell.
Модуль имеет только
контроль над собственным пространством имен - это не может повлиять на то, что люди
может видеть из других пространств имен. Модуль
"реэкспорт" - это всего лишь сокращение, чтобы сказать "экспортировать все
символов в моем собственном пространстве имен, которые
были импортированы из этого другого модуля ". Но символы
которые вы импортировали, на самом деле не находятся в вашем собственном
Пространство имен.
Если вы хотите экспортировать два разных символа, которые
одно и то же имя, вы не сможете сделать это из одного модуля.
Разделите модуль на два и экспортируйте каждую версию из
другой модуль.
Ответ 2
Это ограничение также является удобством, когда модуль импорта предназначен для повторного объявления некоторых имен в импортированном модуле на основе объявлений с квалифицированным импортом. Например:
module MyPrelude (succ, module Prelude) where
import qualified Prelude as P (succ)
import Prelude hiding (succ)
succ :: ...
succ = ... P.succ ...
эту идиому было бы действительно трудно выразить без лишних слов. Кроме того, спросите себя: "это бы имело смысл без иерархических модулей?". Если нет, то это очень специфично для ghc, и то, что на самом деле происходит, когда ссылка на имя иерархического модуля из выражения не является иерархической вообще.
Что касается того, почему вы можете повторно экспортировать отдельные символы, определенные каким-либо именем модуля, которые вы не импортировали, это похоже на kludge, чтобы заставить heirarchical модули работать heirachically в ghc. Получение Foo.B квалифицированных символов при импорте Foo.A является волшебным, и я думаю, что это потому, что имя Foo больше не является фактическим наследником хирахика, чем Foo.A, но предполагаемое использование экспорта предметов с альтернативной квалификацией происходит в тех случаях, когда его использовали от Foo. Я не думаю, что это поведение имеет смысл вообще без расширений GHC, поэтому я собираюсь предположить, что его специфический GHC.