Explicit namespace type import can bring a value into scope
As an example, recall that Data.Functor.Product
exports
data Product f g a = Pair (f a) (g a)
It seems that importing Data.Functor.Product ( Product ( type Pair ) )
imports both the data constructor Pair
(a value) as well as its promotion:
ghci> :seti -XExplicitNamespaces -XDataKinds
ghci>
ghci> import Data.Functor.Product ( Product ( type Pair ) )
ghci>
ghci> :type Pair
Pair
:: forall {k} (f :: k -> *) (g :: k -> *) (a :: k).
f a -> g a -> Product f g a
ghci>
ghci> :kind Pair
Pair :: forall {k} (f :: k -> *) (g :: k -> *) (a :: k).
f a -> g a -> Product f g a
This seems a bit odd: if I'm explicitly asking for the type Pair
, shouldn't I only get the promoted data constructor, and not the value? This is an example of a type
import bringing in a value into scope, which seems odd.
The users' guide isn't very clear about this, but it says that type
is a disambiguation mechanism more than anything else, so if the item is unambiguous then it doesn't change the behaviour, so that in the above example import Data.Functor.Product ( Product ( type Pair ) )
is equivalent to import Data.Functor.Product ( Product ( Pair ) )
.
In the same vein, we have:
ghci> :seti -XExplicitNamespaces -XDataKinds -XPatternSynonyms
ghci>
ghci> import Data.Functor.Product ( pattern Pair )
ghci>
ghci> :type Pair
Pair
:: forall {k} (f :: k -> *) (g :: k -> *) (a :: k).
f a -> g a -> Product f g a
ghci>
ghci> :kind Pair
Pair :: forall {k} (f :: k -> *) (g :: k -> *) (a :: k).
f a -> g a -> Product f g a
In this case we have a pattern
import bringing in a type into scope. I suppose the same reasoning holds as above.