Haddock component for functions in non-importable modules

In module B , I have documentation with the link 'A.foo' referring to the foo member of module A In module A I import module B Haddock displays this as a reference to A.html#t:foo , namely the type foo (which is not), and not the function foo , which is located on A.html#v:foo .

  • Why does Haddock refer to t: for variables starting with a lowercase letter? This is mistake? For 'A.foo' I see that it can be a type or constructor, so there are problems with the namespace. For foo it seems that the variable is at least the most plausible.
  • Is there a way to fake a link? I write this in code samples, so I need it to display as foo . I tried bindings, but they are displayed as the module name, and for direct hyperlinks you do not control the displayed text.
  • I considered the post processor (replacing t:[az] with v: , but this requires a custom Setup.hs that causes problems and is pretty ugly.
  • I could not find the Haddock command line flags to get more reasonable behavior, for example, to indicate that foo is a variable.
  • I cannot add import A to B without introducing cyclic import data, which is vile to add for documentation only.

I ran into this problem in the Shake documentation , where as an example removeFilesAfter correct link fails.

+6
source share
2 answers

This was bug # 228 , and Neil Haddock Error # 253 , and the fix took several months. You can build the GHC HEAD and rebuild your documentation, or wait for 7.8 and do it.

+2
source

I can partially answer the first question (why?); not sure if this is a bug or desired behavior.

When a haddock resolves links in LexParseRn.rename , it tries to find the identifier in the environment (via lookupGRE_RdrName ). This should fail. What looks like next (using dataTcOccs from GHCs RnEnv ). Matching lines:

 dataTcOccs :: RdrName -> [RdrName] -- Return both the given name and the same name promoted to the TcClsName -- namespace. This is useful when we aren't sure which we are looking at. dataTcOccs rdr_name [...] | isDataOcc occ || isVarOcc occ = [rdr_name, rdr_name_tc] [...] where occ = rdrNameOcc rdr_name rdr_name_tc = setRdrNameSpace rdr_name tcName 

therefore, it returns a name that is first interpreted as it was before (probably a reference to a value), and then interpreted as a type constructor. How can a regular name be a type constructor? I assume this was added when TypeOperators were converted to GHC 7.6, which now share the namespace with value-level operators.

Then, a result match is written: if the first one is a type constructor, use it, otherwise use the second. One way or another, it was a type constructor, then it is used. Or it is not, but then a modified version generated by dataTcOccs should be used.

It seems to me that haddock should always use the first option here, and the code is just a misleading copy of how several results are used when they can really be resolved.

+4
source

Source: https://habr.com/ru/post/950482/


All Articles