Changes between Initial Version and Version 1 of Records/NestedModules

Jan 21, 2012 11:10:39 PM (4 years ago)

Pasted from emails. Needs editing.


  • Records/NestedModules

    v1 v1  
     1Proposal for A:
     3Allow nested modules. A nested module can occur in any
     4position that a data declaration can occur. The syntax of
     5a nested module is the same as the syntax of a conventional
     8A nested module must have the same hierarchical name as
     9the module in which it is nested, followed by a single additional
     10component. A name with a single component can be specified
     11in the declaration of a nested module; this is syntactic sugar for
     12the fully qualified name of the enclosing module followed by that
     13single additional component.
     15When a module M.A is directly nested in module M, there is
     16an implied import in the enclosing module M as follows:
     18import qualified M.A as A
     20and an implied import in the nested module M.A as follows:
     22import M
     24These implied imports may optionally be specified explicitly
     25with no effect, or overridden with other explicit imports,
     26similarly to the usual implied import of Prelude.
     28When modules are nested to a depth greater than one,
     29similar implied imports exist for all recursively enclosing
     30and enclosed modules, with the same rules about
     33If an enclosing module M has an export list, a nested
     34module N at any depth recursively cannot be imported
     35by modules not nested inside M unless N is included in
     36the export list of M. If M does not have an export list,
     37N can be imported by any other module as usual.
     39In every other respect, a nested module declaration has
     40exactly the same effect as any other module declaration.
     41In particular, the behavior of nested modules in the
     42presence of all corner cases such as data families, etc.,
     43is specified by this rule.
     45The effect of a nested module on the behavior of
     46ghc --make is left unspecified as of now, until
     47there is feedback from the GHC team. This would
     48probably involve GHC looking for A.B and then
     49A in turn when it fails to find A.B.C. Or perhaps
     50even when A.B.C is found, to identify erroneous
     51duplication. Or GHC could stay pretty much as
     52it is now, relying on the user to ensure that GHC
     53finds the nested module; that would certainly
     54be fine for an initial implementation.
     57Usage example:
     59module Library where
     60 import Data.Text (Text)
     62 type ISBN = Text
     63 module Book where
     64   import Data.Text (Text)
     65   data T = New { name :: Text, iSBN :: ISBN }
     66 module Checkout where
     67   import Data.Time
     68   import qualified Library.Book as Book
     69   import qualified Library.Borrower as Borrower
     70   data T = New
     71     { book :: Book.T, borrower :: Borrower.T, dueDate :: Day }
     72 module Borrower where
     73   import Data.Text (Text)
     74   data T = New { name :: Text, address :: Text }
     75 module History where
     76   import qualified Library.Borrower as Borrower
     77   import qualified Library.Checkout as Checkout
     78   data T = New { borrower :: Borrower.T, checkouts :: [Checkout.T] }
     80This makes available in the module Library the
     81record types:
     83Book.T, Checkout.T, Borrower.T, History.T
     85with constructors:
     87Book.New, Checkout.New, Borrower.New, History.New
     89and record accessors:
     90, Book.iSBN,, Checkout.borrower, Checkout.dueDate,, Borrower.address,
     94History.borrower, History.checkouts
     96I believe this specification should be very simple to
     97implement and describe. There are some obvious
     98shortcomings. But it does provide basic namespacing
     99of records with almost no change to Haskell and GHC.
     101Note also that you need to be careful to avoid mutually
     102recursive imports. That is really more of a limitation
     103of GHC than a limitation of the specification itself.
     104Other compilers might not require that.
     106I'd be happy to hear ideas about how to develop this
     107simple idea further and eliminate some of the
     108shortcomings, on condition that it doesn't lead to
     109further bikeshedding and significant delay.
     111One obvious enhancement would be for the
     112implied import of the enclosing module to
     113include also all names imported into
     114the enclosing module, unlike the usual
     115convention for imports. I'm not sure if
     116there are complications to that though.
     120Whenever any module E imports M unqualified without an
     121import list, as in:
     123import M
     125then the following implied imports would be added to E:
     127import qualified M.T as T
     128import qualified M.S as S
     130and whenever E imports M qualified without an
     131import list, as in:
     133import qualified M as Q
     135then the following implied imports would be
     136added to E:
     138import qualified M.T as Q.T
     139import qualified M.S as Q.S
     141Similarly, if M also contains more deeply nested
     142modules and E imports M either qualified or
     143unqualified without an import list, the corresponding
     144implied imports of the deeply nested modules would
     145also be added to E. But in fact, this is nothing
     146more than a recursive application of the previous
     149Note that an import statement with an import list
     150will never generate any automatic import of
     151a nested module.