-
ExplicitNamespaces -
- Подразумевается расширением:
- Начиная с версии:
-
7.6.1
- Статус:
-
Включено в
GHC2024
Включает использование явных спецификаторов пространства имён
typeиdataв объявлениях импорта, списках экспорта модуля, объявлениях фиксированности и прагмах предупреждений/устаревания; а также спецификатора пространства имёнtypeв выражениях и шаблонах.
6.3.4.1. Ключевое слово type в списках импорта/экспорта
Начиная с версии: GHC 7.6
В списке импорта или экспорта, например
module M( f, (++) ) where ... import N( f, (++) ) ...
сущности f и (++) являются значениями. Однако с операторами типов (Операторы типов) становится возможным объявить (++) как конструктор типа. В таком случае как его экспортировать или импортировать?
Расширение ExplicitNamespaces позволяет добавить к имени конструктора типа в списке импорта или экспорта префикс «type», чтобы устранить эту неоднозначность. Например:
module M( f, type (++) ) where ... import N( f, type (++) ) ... module N( f, type (++) ) where data family a ++ b = L a | R b
Спецификатор пространства имён type также можно использовать во вложенных списках импорта и экспорта:
module N (C(type (#))) where
class C a b where
type a # b
(#) :: a -> b -> (a # b)
module M where
import N as T (C(type (#)))
import N as D (C((#)))
-- (T.#) is the associated type
-- (D.#) is the class method
Расширение ExplicitNamespaces подразумевается расширениями TypeOperators и (по какой-то причине) TypeFamilies.
6.3.4.2. Ключевое слово data в списках импорта/экспорта
Начиная с версии: GHC 9.14
В списке импорта или экспорта, например
module M( T ) where ... import N( T ) ...
сущность T обозначает конструктор типа, даже если существует конструктор данных или синоним шаблона с тем же именем.
В качестве конкретного примера рассмотрим объявление data Proxy t = Proxy и следующие импорты:
import Data.Proxy (Proxy(Proxy)) -- imports both constructors import Data.Proxy (Proxy(..)) -- imports both constructors import Data.Proxy (Proxy) -- imports the type constructor only import Data.Proxy (type Proxy) -- imports the type constructor only
Но как импортировать только конструктор данных? Есть два варианта:
import Data.Proxy (data Proxy) -- imports the data constructor only import Data.Proxy (pattern Proxy) -- imports the data constructor only
Ключевое слово data позволяет импортировать или экспортировать конструктор данных без родительского конструктора типа.
Ключевое слово pattern выполняет ту же задачу, но имеет несколько отличий:
-
Требуемые версии компилятора и флаги
-
patternпредоставляется расширениемPatternSynonymsи требует GHC ≥7.8 -
dataвключается расширениемExplicitNamespacesи требует GHC ≥9.14
См. раздел Импорт и экспорт синонимов шаблонов.
-
-
Ограничения на использование
-
Использование
patternограничено импортом синонимов шаблонов и конструкторов данных на верхнем уровне:import N (pattern P) -- ok (top-level) import N (T(pattern P)) -- error (subordinate) import N (pattern f) -- error (term or field selector)
-
dataтакже допускается во вложенных списках импорта/экспорта и применимо к объявлениям терминов (функциям и константам), а также к селекторам полей:import N (data P) -- ok (top-level) import N (T(data P)) -- ok (subordinate) import N (data f) -- ok (term or field selector)
-
В списках импорта/экспорта предпочтительно использовать ключевое слово data вместо pattern, если нет необходимости поддерживать более старые версии GHC.
6.3.4.3. Явные пространства имён в объявлениях фиксированности и прагмах предупреждений/устаревания
Начиная с версии: GHC 9.10
Если включено расширение ExplicitNamespaces, можно использовать ключевые слова type и data, чтобы указать пространство имён имени, используемого в сигнатуре фиксированности или прагме WARNING/DEPRECATED. Это может быть полезно для устранения неоднозначности между именами из разных пространств имён, которые могут конфликтовать друг с другом.
Ниже приведён пример использования спецификаторов пространства имён для задания разных правил фиксированности для операторов уровня типов и уровня терминов:
type f $ a = f a f $ a = f a infixl 9 type $ -- type-level $ is left-associative with priority 9 infixr 0 data $ -- term-level $ is right-associative with priority 0
Аналогично, их можно использовать в прагмах, чтобы объявить устаревшим только одно имя в пространстве имён:
data Solo a = MkSolo a
pattern Solo x = MkSolo x
{-# DEPRECATED data Solo "Use `MkSolo` instead" #-}
type family Head xs where
Head (x : _) = x
pattern Head x <- (head -> x)
{-# WARNING in "x-partial" data Head "this is a partial type synonym" #-}
Считается плохой практикой использовать сигнатуру фиксированности, прагму WARNING или прагму DEPRECATED для имени уровня типов без явного пространства имён type. В будущей версии GHC это станет ошибкой.
6.3.4.4. Ключевое слово type в выражениях и шаблонах
Начиная с версии: GHC 9.10
Кроме того, расширение ExplicitNamespaces разрешает использовать ключевое слово type в шаблонах и выражениях:
f (type t) x = ... -- in a pattern r = f (type Integer) 10 -- in an expression
Оно используется совместно с расширением RequiredTypeArguments.