haskell / haddock

Haskell Documentation Tool

Home Page:www.haskell.org/haddock/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

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

Seems reasonable to make this two options: link with explicit import, link with explicit hiding.