Spec-Zone.ru › Haskell 9

6.3.4. Явные пространства имён в импорте/экспорте

ExplicitNamespaces
Подразумевается расширением:

TypeOperators, TypeFamilies

Начиная с версии:

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.

© 2002–2007 The University Court of the University of Glasgow. All rights reserved.
Licensed under the Glasgow Haskell Compiler License.
https://downloads.haskell.org/~ghc/9.14.1/docs/users_guide/exts/explicit_namespaces.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API