Что является альтернативой прелюдии с qualfied import
Почти каждый модуль в нашей базе кода имеет импорт, такой как:
import qualified Data.Map as Map
import qualified Data.Set as Set
import qualified Data.Text as Text
Я хотел бы определить локальную прелюдию, чтобы Map
, Set
и Text
были доступны для модулей, импортирующих эту прелюдию. По-видимому , в Haskell нет никакого способа сделать это. Поэтому мне интересно, как люди решают эту проблему в больших базах кода Haskell.
Ответы
Ответ 1
Одним из решений является определение списка импорта в заголовке CPP.
NB: Этот ответ - это просто показать, что технически возможно; Ответ Даниэля Вагнера, как правило, является лучшей альтернативой.
Для примера на уровне пакета:
my-pkg/
my-pkg.cabal
include/imports.h
src/MyModule.hs
...
include/imports.h
:
import Control.Applicative
import Data.Maybe
import Data.Char
В my-pkg.cabal
компоненты (library
, executable
, test
,...) имеют поле include-dirs
(что в свою очередь соответствует некоторой опции GHC):
library
...
include-dirs: include
Затем вы можете использовать этот заголовок в любом модуле:
{-# LANGUAGE CPP #-}
module MyModule where
#include "imports.h"
-- your code here
mymaybe = maybe
Ответ 2
Я собираюсь ответить на этот вопрос, интерпретируя его как можно более буквально:
Как люди решают эту проблему в больших базах кода Haskell?
Ответ: они пишут
import qualified Data.Map as Map
import qualified Data.Set as Set
import qualified Data.Text as Text
в верхней части каждого модуля, который нуждается в Map
, Set
и Text
.
По моему опыту, управление импортом не является существенной частью сложности работы с большими кодовыми базами. Усилия прыжка в список импорта и добавление строки для Data.Map
когда вы обнаружите, что вам это нужно, абсолютно захлестнуто стремлением найти нужное место в кодовой базе для внесения изменений, зная полную ширину кодовой базы, чтобы вы не дублировать усилия и находить способы проверки небольших фрагментов большого приложения изолированно.
По сравнению с предлагаемой альтернативой в другом ответе (CPP), этот способ также имеет некоторые технические преимущества:
- Меньше времени ввода проекта. Чем меньше сюрпризов для людей, которые присоединяются к вашему проекту, тем быстрее они могут встать и работать и быть независимо полезными.
- Лучшая поддержка инструмента. Если я где-то вижу
Foo.bar
в качестве идентификатора, я могу использовать поиск в регулярном выражении текстового редактора, чтобы узнать, какая строка импорта сделала пространство имен Foo
доступным без фантастических дополнений, чтобы включить #include
d файлы. Если я хочу найти все файлы, которые зависят от Some.Fancy.Module
, я могу узнать, что grepping для Some.Fancy.Module
. Создавать системы, которые выполняют обнаружение изменений, не обязательно знать о дополнительном файле .h
при .h
файлов, которые нужно посмотреть. И так далее. - Меньше ложных перестроек. Если у вас больше импорта, чем вы на самом деле используете, это может привести к тому, что GHC перестроит ваш модуль, даже если его не нужно перестраивать.