2010-07-08 3 views
18

Я хочу написать модуль, который реэкспортирует некоторый модуль, который он импортировал. Что-то вроде этого: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 экспорт этих модулей?

ответ

12

Нет, это не просто ограничение GHC, это способ импорта , а экспорт предназначен для работы в Haskell.

Модуль имеет только контроль собственного пространства имен - он не может повлиять на то, что люди могут видеть из других пространств имен. Модуль «реэкспорт» - это всего лишь сокращение, чтобы сказать «экспортировать все символов в моем собственном пространстве имен, которые, как оказалось, были импортированы из этого другого модуля» ». Но символы , которые вы импортировали, на самом деле не находятся в вашем собственном пространстве имен .

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

+4

Но можно переэкспортировать квалифицированные символы; например, 'import qualified Foo.B' позволит мне сделать модуль Foo.A (Foo.B.sym)'. Почему это невозможно с модулями? Я не экспортирую два символа с тем же именем; что-либо противоречивое является внутренним для модуля. –

6

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

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 специфичен.

Смежные вопросы