6.3.4. Explicit namespaces in import/export¶
-
ExplicitNamespaces
¶ Implied by: TypeOperators
,TypeFamilies
Since: 7.6.1 Status: Included in GHC2024
Enable use of explicit namespaces in module export lists, patterns, and expressions.
In an import or export list, such as
module M( f, (++) ) where ...
import N( f, (++) )
...
the entities f
and (++)
are values. However, with type
operators (Type operators) it becomes possible to declare
(++)
as a type constructor. In that case, how would you export or
import it?
The ExplicitNamespaces
extension allows you to prefix the name of
a type constructor in an import or export list with “type
” to
disambiguate this case, thus:
module M( f, type (++) ) where ...
import N( f, type (++) )
...
module N( f, type (++) ) where
data family a ++ b = L a | R b
The extension ExplicitNamespaces
is implied by
TypeOperators
and (for some reason) by TypeFamilies
.
In addition, with PatternSynonyms
you can prefix the name of a
data constructor in an import or export list with the keyword
pattern
, to allow the import or export of a data constructor without
its parent type constructor (see Import and export of pattern synonyms).
Furthermore, ExplicitNamespaces
permits the use of the type
keyword in patterns and expressions:
f (type t) x = ... -- in a pattern
r = f (type Integer) 10 -- in an expression
This is used in conjunction with RequiredTypeArguments
.
When ExplicitNamespaces
is enabled, it is possible to use the
type
and data
keywords to specify the namespace of the name used in
a fixity signature or a WARNING
/DEPRECATED
pragma. This can be useful for disambiguating
between names in different namespaces that may conflict with each other.
Here is an example of using namespace specifiers to set different fixities for type-level and term-level operators:
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
Similarly, it can be used in pragmas to deprecate only one name in a namespace:
data Solo = MkSolo
pattern Solo = MkSolo
{-# 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" #-}
It is considered bad practice to use a fixity signature, WARNING
pragma, or
DEPRECATED
pragma for a type-level name without an explicit type
namespace, and
doing so will become an error in a future version of GHC.