Re-export behavior
parsonsmatt opened this issue · comments
Currently if you re export a module with an alias, it dumps all of the contents of that module directly.
module M
( module X
) where
import ClassyPrelude as X hiding (...)
import FooBar as X
import BlahBaz as X
This can quite quickly cause performance issues, particularly if you re-export these things.
module M2 ( module X ) where
import M as X
import Neat as X
module M3 (module X) where
import M2 as X
import A as X
Even if you re-export with the original module name, if you hide
anything or only import a specific list, you get a dump of everything:
module M (module Prelude, module Data.Text) where
import Prelude hiding (String)
import Data.Text (Text)
This is Bad both for performance reasons and legibility reasons. Tracking the provenance of re-exports is difficult, and exploding everything onto a page is bad. On the other hand, presenting only a link doesn't allow you to understand the "index" of that module - everything that is exported from it.
Related:
- #958 requests that we have a per-module flag to expand the docs - so re-exporting a named module doesn't link, it actually pastes the docs in.
- #1106 requests export-item-level annotations for hiding and showing things
- #1524 is a bug report stating that section information is missing when re-exporting the "self" module -
module X (module X, ...) where
. - #944 reports the same basic thing as a problem, though it is "by design".
So - let's talk about possible designs for improving the situation.
Goals
- Flexible: You can pick and choose how you want a re-exported module to show up.
- Indexable: You should be able to see everything exported by a module, even if the totality of the documentation isn't rendered out.
- Structured: If documentation is exploded into the current scope, it should try to retain the structure of the original module.
Status Quo
We have essentially two status quo situations: Linking a module (if the module is exported intact and without a shared alias), and totally verbose and unorganized (dumping the docs for the module in whatever order makes sense).
Linking a module isn't great, because we can't know at-a-glance (or Ctrl-F
) what a module contains and allows you to use.
Dumping the entire module contents isn't great, because it's totally disorganized (and also can be huge - one of our Prelude-ish modules exploded to 250MB of HTML, hundreds of pages printed as a PDF).
Options
Expand Alias and Link Complete Modules
One easy change that would require little modification would be to "expand" an alias and provide links where possible.
module M (module X) where
import Prelude as X
import Data.Text as X (Text)
import BigModule as X
import LittleModule as X hiding (foo)
If this option were enabled, Hadock would do the same thing as if you wrote this:
module M
( module Prelude
, module Data.Text
, module BigModule
, module LittleModule
)
import Prelude
import Data.Text (Text)
import BigModule
import LittleModule hiding (foo)
Instead of dumping Prelude
and BigModule
's contents directly, you'd get a link to those two modules.
Modified Modules are Grouped
If this option is enabled, then a modified module is "grouped" with a section. A module like this:
module M (module X) where
import Prelude as X hiding (String)
import Data.Maybe as X hiding (fromJust)
would be rendered as though the user wrote:
module M
( -- * "Prelude"
module Prelude
-- * "Data.Maybe"
, module Data.Maybe
) where
import Prelude hiding (String)
import Data.Maybe hiding (fromJust)
Searchable Indexes
With this option enabled, a module would contain an 'index' of everything the module exports, even if the module is linked. The index can take the form of the current "index pages" - just a list of items, paired with the module that brought it into scope (+ maybe the module that defined it?)
This would require more work than the prior two choices, since we'd be adding stuff to the page, rather than "reinterpreting" the export items.
Link with Changes
With this option enabled, a module re-export that alters the exports would show a link and report what was changed.
module M (module X) where
import Prelude hiding (String)
import Data.String (IsString(..))
The above module should generate documentation looking something like:
module M where
module Prelude
- hiding
String
module Data.String
- only
IsString
Seems reasonable to make this two options: link with explicit import, link with explicit hiding.