Qualified Imports
Import lists help to avoid name clashes in many situations but not always. There
are numerous widely used packages whose modules provide functions with the same
names, and with good reason. For example, there exists a map function for
lists (defined in Data.List and also included in the Prelude), and the
Data.Array module of the array package also provides a map function, one
that operates on arrays. Given that these two functions do the same thing—only
one does it for lists, and the other for arrays—it is a good thing that they
have the same name. The user of the Data.Array module recognizes the familiar
function name and can immediately guess what the function does. However, it is
not uncommon to implement modules that need to manipulate both arrays and lists,
and thus may need access to both the map function for lists and the map
function for arrays. After importing Data.Array even with an explicit import
list
import Data.Array (map)
our module can no longer call just map anywhere, because there are now two
map functions in scope, and the compiler cannot tell which one we want to
call. We can disambiguate the function calls by using qualified function names.
Every function f imported from some module M can be called using its fully
qualified name M.f. Thus, we could distinguish between the map function
(automatically) imported from the Prelude and the map function imported from
Data.Array by calling either Prelude.map or Data.Array.map.
We can avoid having to use one of these qualifications by using qualified imports. If we use the import statement
import qualified Data.Array
then every function imported from Data.Array can only be called using its
qualified name. Thus, calling map once again refers to the map function from
the Prelude. To call the map function from Data.Array, we must use the
fully qualified name Data.Array.map.
When using qualified imports, it is common to omit an explicit import list. Since the definitions from the module are imported using only their qualified names, importing everything from such a module cannot cause any name clashes, and calling any function from such a module cannot leave the reader of our code guessing which module defines the function we're calling because we must call the function using its fully qualified name. However, it is allowed to combine qualified imports and import lists, as in
import qualified Data.Array (map)
This says that we want to import only the map function from Data.Array and
that the import is qualified, that is, we can call this function in the current
module only using its fully qualified name Data.Array.map.
It is also common to combine both qualified and unqualified imports of the same module. For example, many Haskell programmers find qualified names in type signatures distasteful but are perfectly fine with using qualified names in function definitions. So they end up importing types unqualified, and functions qualified. For example,
import Data.Array (Array)
import qualified Data.Array
allows us to use the Array type in type signatures in its unqualified form,
because we imported it using an unqualified import of Data.Array. All
functions from the Data.Array module need to be called using their fully
qualified names (e.g., Data.Array.map).