haskell / haddock

Haskell Documentation Tool
www.haskell.org/haddock/
BSD 2-Clause "Simplified" License
361 stars 241 forks source link

Types appear as duplicates because of defaulting #1048

Open monoidal opened 5 years ago

monoidal commented 5 years ago

Haddock can show multiple types for an expression, more or less specific (e.g. id in id 'a' is Char -> Char or a -> a). Sometimes, the same type is shown twice because of RuntimeRep defaulting. Example:

{-# LANGUAGE ExplicitForAll, GADTs, KindSignatures, PolyKinds, DataKinds #-}
module M where

import GHC.Types

data Foo :: forall (k :: *). k -> * where
  R :: forall (r :: RuntimeRep). Foo r

z :: Foo 'LiftedRep
z = R

With haddock M.hs --hyperlinked-source --html, the last R in the source is given type Foo 'LiftedRep twice. There are two possible fixes:

  1. Display both versions correctly. In recoverFullIfaceTypes we use showSDoc df . pprIfaceType to show the type. Fix: define df' = gopt_set df Opt_PrintExplicitRuntimeReps and use showSDoc df' . pprIfaceType.

  2. Don't display duplicates. Fix: in Haddock/Backends/Hyperlinker/Renderer.hs

@@ -162,7 +168,7 @@ annotate  ni content =
           Html.thespan (Html.toHtml annotation) ! [ Html.theclass "annottext" ]
       | otherwise = mempty
     annotation = typ ++ identTyps
-    typ = unlines (nodeType ni)
+    typ = unlines (nub (nodeType ni))
     typedIdents = [ (n,t) | (n, identType -> Just t) <- Map.toList $ nodeIdentifiers ni ]
     identTyps
       | length typedIdents > 1 || null (nodeType ni)

This issue becomes important for linear types. In linear types, every data constructor with at least one argument has Multiplicity arguments (which, like RuntimeReps, are hidden, and cause duplicates).

Using GHC master, haddock commit 65bbdfb6dc1b08f89.

harpocrates commented 5 years ago

Nice catch! I would lean towards option 2, since runtime reps are supposed to be mostly hidden from users.

Sometime in the 8.10 release cycle, Haddock will add a file-level option show-runtime-reps which will cause docs for that module to print explicit runtime reps. That option should also carry over to the module's hyperlinked sources. But this makes me think: perhaps Haddock could benefit from a similar option for printing the full multiplicity arguments in linear types too?

Thoughts?