Using the GHC API: pretty printing with qualified names

Simon Peyton-Jones simonpj at
Wed Nov 17 16:31:48 EST 2010

I'm trying to give the user the possibility to jump to the definition of a symbol in the source file. You click on the name of a function and you're send to the module where it's defined. So I have an AST, and somewhere down the line I have an Id object representing that function call. Then I just use ppr alwaysQualify id to get the fully qualified name of the function, and I can then use the module name to retrieve the source file etc.

No, no, don't do this.  The ppr alwaysQualify thing tries hard to display the thing *in the current scope*.  So if you have
         import M as N
it will, I think, print thing as N.f, N.g, etc, not as M.f, M.g.  The intent is to give user-comprehensible error messages.

What you want is to use
         idName :: Id -> Name
         nameModule_maybe :: Name -> Maybe Modlue

The latter gives you the *defining* module for the Id, which is what you wanted. It returns nothing for local variables (e.g. lambda-bound).

This works well in cases, but not in others. It will sound silly to the gurus on the list, but it's when the function has generics that it doesn't work. So a function with a type class in its type signature will never be printed qualified. It kinda like makes sense because I suppose some work has been done so that it represents the function with proper types, etc., but how can I get back to the original Id? How can I get back from that unqualified Id to the qualified Id representing the function in the original module? I've been looking round Name and OccName and all that but I'm not sure really what I'm looking for.

Suppose we have  List.sort :: Ord a => [a] -> [a].  And the program is

f x = sort [x,x]

Then, after type checking, the code looks more like this:

f :: Ord a => a -> [a]
f = /\a. \d:Ord a.  let  s :: [a] -> [a]
                                  s = List.sort a d
                            in \(x:a). s [x,x]

Notice the local function 's'.  (Well, its string-name is still "sort", but it's not the global List.sort.)  I think you are poking on 's'.

Happily, GHC 7 takes a simpler approach, and instead generate something more like
f :: Ord a => a -> [a]
f = /\a. \d:Ord a.
       \(x:a). List.sort a d [x,x]

So it may "just work" in GHC 7.

Hope this helps.

Good luck with EclipseFP.  We need a good Haskell IDE.

-------------- next part --------------
An HTML attachment was scrubbed...

More information about the Glasgow-haskell-users mailing list