Using the GHC API: pretty printing with qualified names

Claus Reinke claus.reinke at talk21.com
Thu Nov 18 04:53:05 EST 2010


> scion-server mimics a GHCi command line, of sorts. scion-server 
> is used very successfully to syntax-highlight the Eclipse editor, 
> show a source's outline, provide type information when hovering 
> over a name, and provide completions.

> That's not the problem, per se. Let's say I'm hovering over a 
> function that's imported by Data.Map. When resolved, the 
> symbols appear to come from Ghc.Map (if memory serves 
> correctly), which makes finding the correct "haddock" impossible.

"Impossible" is such an ugly word;-)

The problem you encounter is that the GHC API is still, to a 
large part, just an open window into what happens to be 
in GHC. Since GHC's aims as a compiler differ from those 
of IDEs, its exposed functionality will sometimes be too 
limited to serve your purposes (eg, if GHC knows where
a function is defined, it doesn't need to know how it was
imported, once it gets past error reporting). 

If you tie yourself too closely to GHC's view, some things 
you'd like to do in an IDE will _appear_ to be impossible. 
That is why I recommend looking into the GHCi sources, 
because GHCi's needs are closer to those of an IDE.

I assume you mean things like Data.List.map being a 
re-exported GHC.List.map being a re-exported GHC.Base.map, 
and :info not knowing about  the intended abstractions:

    Prelude> :i map
    map :: (a -> b) -> [a] -> [b]   -- Defined in GHC.Base

You can actually get information about possible import 
paths via :browse!

    Prelude> :m +Data.List
    Prelude Data.List> :grep map|imported :browse!

    -- imported via Data.List
    mapAccumL :: (acc -> x -> (acc, y)) -> acc -> [x] -> (acc, [y])
    mapAccumR :: (acc -> x -> (acc, y)) -> acc -> [x] -> (acc, [y])
    -- imported via Data.List, Prelude
    map :: (a -> b) -> [a] -> [b]

(:browse! is standard GHCi, :grep is non-standard, just to filter
:browse! output). So the :browse! command seems to be able
to find more of the information you want.

haskellmode for Vim, on the other hand, has long provided
haddock lookup, and will offer you a menu of possible 
destinations when your cursor is over 'map'. This menu is 
built from an index of Haddock entries, which is extracted 
from installed Haddock documentation. 

Nothing impossible about that, just ugly: so far, the index 
is scraped from Haddock's HTML index files. That route
breaks occasionally (recent Haddock HTML changes, 
ghc-pkg listing wrong Haddock paths, ..; I'm about to 
publish updated scraping code for GHC-7.0.1's Haddock..).

To get something less ugly, I'm currently recoding the 
extraction by using Haddock's API and .haddock files
(that'll still break when the API changes, also there is 
a pending bug about ghc-pkg, cabal, and haddock 
disagreeing about filepath formats, meaning that
.haddock files aren't found on Windows). 

I assume that code will be useful to other Haskell IDEs,
though it is mostly exposing Haddock's internal ability to
build an index from .haddock files, which I'd like to see
exposed in Haddock's less-than-well-known API:

    http://trac.haskell.org/haddock/ticket/157

Claus

 


More information about the Glasgow-haskell-users mailing list