Cross-package Documentation

The purpose of this page is to talk about how we could implement http://trac.haskell.org/haddock/ticket/24. When we have settled on a way to do it, we can also use this page to describe the implementation.

Overview

Currently, when you export an identifier from another package, only the identifier name is listed in the documentation. There is no declaration and no Haddock comments. The identifier can link to the documentation for the identifier in the external package, if you have that documentation installed, and you pass the right flags to Haddock.

What we want is to show the documentation for the identifier in-place. That is, we want the declaration and the Haddock comments to show up just like in the normal case, when the identifier comes from the same package.

To do this, we need some way to access the declaration syntax and the comments for the external identifier when we are processing the package.

Comments

Haddock can generate .haddock files for packages, which contain the link environment and the comments (among other things). We can get the comments for an external identifier from the .haddock file of the external package, provided that the user has passed the file to Haddock. This requirement should be fine since this is normally done anyway, to get working links to the documentation of the external package.

Declarations

Storing Declarations in .haddock Files

One way to get at the declarations, is to store them in the .haddock files. We would have to define Binary instances for all the HsSyn syntax types that we use.

Reconstructing Declarations from .hi Files

We might not need to store anything in the .haddock files if we can reconstruct all declarations from the TyThings available in the .hi files. We already convert instances using a conversion function toHsType :: Type -> HsType Name. We could try to write a conversation function toHsDecl :: TyThing -> HsDecl Name.

It might also be possible to do the conversion using existing Template Haskell functionality in GHC. Template Haskell lets you reify an identifier, which returns the abstract syntax of its declaration (or type). Internally to GHC, the implementation of reify turns a TyThing into a TH.Dec. There is also functionality in Template Haskell that turns TH.Dec into HsSyn, for compilation by GHC (see hsSyn/Convert.lhs). Hence, in theory we have all the bits to get from TyThing to HsSyn already in GHC, we just have to connect them up.

The downside of this approach is that we lose the original declaration style. For example, we don't know if a data type was declared using GADT-style syntax (with a 'where' clause), or normal style. Other examples:

  • We can't put in extra parenthesis where the user wants them.
  • Sometimes users want non-operators to be defined and used in infix form, an example is Conal's type composition `O`.

Any information missing from the TyThing version of the declaration (such as whether to use GADT-style for datatype declarations) can always be added to the .haddock file, though.