Skip to content

Re-Exporting Whole Modules

The above process of importing a specific list of symbols from another module and then listing each individual symbol to be re-exported gets tedious very quickly. It isn't uncommon to want to re-export all the symbols imported from a given module. To support this, GHC allows us to list the modules to be exported in the current module's export list, like so:

Banner.hs
module Banner
    ( module Banner.StudentRecord
    , module Banner.Transcript
    , module Banner.Database
    , module Banner.WebInterface
    ) where

import Banner.StudentRecord
    (StudentRecord, bannerNumber, name, address, transcript)
import Banner.Transcript
    (Transcript)
import Banner.Database
    (retrieveRecords, storeRecords)
import Banner.WebInterface
    (processWebQuery)

Using module A in the export list of module B is allowed only if B imports all of A using

import A

or a list of specific symbols from A using

import A (sym1, sym2, ...)

Listing module A as an export of module B then makes B export all the symbols it imports from A. To be specific, it exports all symbols that are imported unqualified from A. Thus, while the following module definition would be legal:

module B (module A) where

import qualified A

it would (usually) not export anything because all symbols imported from A are accessible only using their qualified names A.sym1, A.sym2, ....

I said "usually" just now because there is a weird corner case. Consider the following module definition

module B (module Data.List) where

import qualified Data.List

In this case, B exports all those symbols from the Data.List module that are accessible using their unqualified names. Since every module automatically imports the Prelude, and the Prelude includes some functions from Data.List, this definition of the module B would actually lead to B exporting some functions, namely exactly those that come from Data.List and which are also included in (re-exported by) the Prelude. I'm not sure this is the best possible behaviour, but I'm sure there is a reason why the Haskell standard defines the behaviour of module exports in this manner.