How to determine the right path to haddock html documentation?

Hi, I'm writing a patch for ghcmod-vim so that a user can look up the haddock html documentation for a symbol. My code makes three system calls, e.g. to look up "Just" it does: $ ghc-mod info foo.hs Foo Just data Maybe a = ... | Just a -- Defined in `Data.Maybe' $ ghc-pkg find-module Data.Maybe --simple-output haskell2010-1.1.1.0 base-4.6.0.1 $ ghc-pkg field base-4.6.0.1 haddock-html haddock-html: /home/carlo/opt/ghc-7.6.3_build/share/doc/ghc/html/libraries/base-4.6.0.1 Then "Data.Maybe" is changed to Data-Maybe.html" and appended to the haddock-html value. But this procedure doesn't work in general, for example when looking up String: $ ghc-mod info foo.hs Foo String type String = [Char] -- Defined in `GHC.Base' $ ghc-pkg find-module GHC.Base /home/carlo/opt/ghc-7.6.3_build/lib/ghc-7.6.3/package.conf.d base-4.6.0.1 /home/carlo/.ghc/x86_64-linux-7.6.3/package.conf.d $ ghc-pkg field base-4.6.0.1 haddock-html haddock-html: /home/carlo/opt/ghc-7.6.3_build/share/doc/ghc/html/libraries/base-4.6.0.1 $ ls /home/carlo/opt/ghc-7.6.3_build/share/doc/ghc/html/libraries/base-4.6.0.1/GHC-Base.html ls: cannot access /home/carlo/opt/ghc-7.6.3_build/share/doc/ghc/html/libraries/base-4.6.0.1/GHC-Base.html: No such file or directory because the html is in the src subdirectory: $ ls /home/carlo/opt/ghc-7.6.3_build/share/doc/ghc/html/libraries/base-4.6.0.1/src/GHC-Base.html /home/carlo/opt/ghc-7.6.3_build/share/doc/ghc/html/libraries/base-4.6.0.1/src/GHC-Base.html But this isn't even the right place to go, one should look at the Prelude file http://hackage.haskell.org/package/base-4.6.0.1/docs/Prelude.html#t:String which is what Hoogle suggests. How does Hoogle get it right? It looks like haskell-mode for emacs runs into a similar problem: https://github.com/haskell/haskell-mode/blob/master/inf-haskell.el#L734-L740 ------------------------------- (defvar inferior-haskell-ghc-internal-ident-alist ;; FIXME: Fill this table, ideally semi-automatically. '(("GHC.Base.return" . "Control.Monad.return") ("GHC.List" . "Data.List"))) (defun inferior-haskell-map-internal-ghc-ident (ident) "Try to translate some internal GHC identifier to its alter ego in haskell docs." ------------------------------- Thanks, -- Carlo Hamalainen http://carlo-hamalainen.net

String is defined in GHC.Base, but GHC.Base is an internal (not exposed)
module of the base package; that's why there's no documentation for it.
Instead of asking where the thing is defined, you should be asking where
it's exported from. In this case, String is re-exported from Prelude.
Roman
* Carlo Hamalainen
Hi,
I'm writing a patch for ghcmod-vim so that a user can look up the haddock html documentation for a symbol. My code makes three system calls, e.g. to look up "Just" it does:
$ ghc-mod info foo.hs Foo Just data Maybe a = ... | Just a -- Defined in `Data.Maybe'
$ ghc-pkg find-module Data.Maybe --simple-output haskell2010-1.1.1.0 base-4.6.0.1
$ ghc-pkg field base-4.6.0.1 haddock-html haddock-html: /home/carlo/opt/ghc-7.6.3_build/share/doc/ghc/html/libraries/base-4.6.0.1
Then "Data.Maybe" is changed to Data-Maybe.html" and appended to the haddock-html value. But this procedure doesn't work in general, for example when looking up String:
$ ghc-mod info foo.hs Foo String type String = [Char] -- Defined in `GHC.Base'
$ ghc-pkg find-module GHC.Base /home/carlo/opt/ghc-7.6.3_build/lib/ghc-7.6.3/package.conf.d base-4.6.0.1 /home/carlo/.ghc/x86_64-linux-7.6.3/package.conf.d
$ ghc-pkg field base-4.6.0.1 haddock-html haddock-html: /home/carlo/opt/ghc-7.6.3_build/share/doc/ghc/html/libraries/base-4.6.0.1
$ ls /home/carlo/opt/ghc-7.6.3_build/share/doc/ghc/html/libraries/base-4.6.0.1/GHC-Base.html ls: cannot access /home/carlo/opt/ghc-7.6.3_build/share/doc/ghc/html/libraries/base-4.6.0.1/GHC-Base.html: No such file or directory
because the html is in the src subdirectory:
$ ls /home/carlo/opt/ghc-7.6.3_build/share/doc/ghc/html/libraries/base-4.6.0.1/src/GHC-Base.html
/home/carlo/opt/ghc-7.6.3_build/share/doc/ghc/html/libraries/base-4.6.0.1/src/GHC-Base.html
But this isn't even the right place to go, one should look at the Prelude file
http://hackage.haskell.org/package/base-4.6.0.1/docs/Prelude.html#t:String
which is what Hoogle suggests. How does Hoogle get it right?
It looks like haskell-mode for emacs runs into a similar problem:
https://github.com/haskell/haskell-mode/blob/master/inf-haskell.el#L734-L740
------------------------------- (defvar inferior-haskell-ghc-internal-ident-alist ;; FIXME: Fill this table, ideally semi-automatically. '(("GHC.Base.return" . "Control.Monad.return") ("GHC.List" . "Data.List")))
(defun inferior-haskell-map-internal-ghc-ident (ident) "Try to translate some internal GHC identifier to its alter ego in haskell docs." -------------------------------
Thanks,
-- Carlo Hamalainen http://carlo-hamalainen.net
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

On 13/12/13 23:28, Roman Cheplyaka wrote:
String is defined in GHC.Base, but GHC.Base is an internal (not exposed) module of the base package; that's why there's no documentation for it.
Right.
Instead of asking where the thing is defined, you should be asking where it's exported from. In this case, String is re-exported from Prelude.
To do this will I have to dig into the GHC API? Perhaps I could extract the imports from a file, then use parseImportDecl to parse them, and then do interactive imports, using IIDecl (ImportDecl RdrName) Bring the exports of a particular module (filtered by an import decl) into scope until the name appears in scope, checking with getNamesInScope? I haven't used the GHC API before so I may be barking up the wrong tree. Thanks, -- Carlo Hamalainen http://carlo-hamalainen.net

* Carlo Hamalainen
On 13/12/13 23:28, Roman Cheplyaka wrote:
String is defined in GHC.Base, but GHC.Base is an internal (not exposed) module of the base package; that's why there's no documentation for it.
Right.
Instead of asking where the thing is defined, you should be asking where it's exported from. In this case, String is re-exported from Prelude.
To do this will I have to dig into the GHC API?
Yes. haskell-names can also do this (it's used in halberd to solve a similar task: https://github.com/haskell-suite/halberd) But since ghc-mod is based on the GHC API, you should probably stick to it. I'm not familiar with the GHC API either; hopefully, someone else will help you here. Roman

On 14/12/13 15:02, Roman Cheplyaka wrote:
haskell-names can also do this (it's used in halberd to solve a similar task: https://github.com/haskell-suite/halberd)
This is quite useful, thanks. For the benefit of the list archive, here is what I have worked out so far. I took the example from http://www.haskell.org/haskellwiki/GHC/As_a_library which uses getNamesInScope (I thought that this was promising). But it returned an empty list for the list of names (variable 'n'). I found out that you have to set the context before the call to getNamesInScope, like so: https://github.com/carlohamalainen/playground/blob/master/haskell/ghc_symbol... target <- guessTarget targetFile Nothing setTargets [target] load LoadAllTargets -- http://stackoverflow.com/questions/11571520/reify-a-module-into-a-record setContext [IIDecl (simpleImportDecl (mkModuleName "B"))] modSum <- getModSummary $ mkModuleName "B" For example on this file, -- B.hs module B where import Data.Maybe f :: a -> Maybe a f x = Just x s = "boo" :: String main = print "Hello, World!" we can get the list of names and also the imports: $ runhaskell A.hs ([B.main, B.f, B.s], [main, B.main, f, B.f, s, B.s], [], [import (implicit) Prelude, import Data.Maybe]) I'm not sure why, but the "source imports" is an empty list, while the "textual imports" gives the implicit Prelude and Data.Maybe. Also the names are the program names like f, s, and main, and don't include things like String, Int, Just, and so on. Independently of that, I tweaked an example from the haskell-names docs and this lets me see where String comes from, e.g. https://github.com/carlohamalainen/playground/blob/master/haskell/ghc_symbol... $ cat B.hs | runhaskell haskell_names_example.hs Relevant bits: "Prelude" SymType {st_origName = OrigName { origPackage = Just (PackageIdentifier { pkgName = PackageName "base" , pkgVersion = Version {versionBranch = [4,7,0,0] , versionTags = []}}) , origGName = GName { gModule = "GHC.Base" , gName = "String"}} , st_fixity = Nothing} "Data.Maybe" SymConstructor {sv_origName = OrigName { origPackage = Just (PackageIdentifier { pkgName = PackageName "base" , pkgVersion = Version {versionBranch = [4,7,0,0] , versionTags = []}}) , origGName = GName { gModule = "Data.Maybe" , gName = "Just"}} , sv_fixity = Nothing , sv_typeName = OrigName { origPackage = Just (PackageIdentifier { pkgName = PackageName "base" , pkgVersion = Version { versionBranch = [4,7,0,0] , versionTags = []}}) , origGName = GName { gModule = "Data.Maybe" , gName = "Maybe"}}} This is pretty much what I'm after. The first block shows us that String is exported from the Prelude, even though it's defined in GHC.Base. The second block says that the constructor Just is actually exported from Data.Maybe. So these ought to able to be stitched together: work through the textual imports one at a time until a symbol appears and then find the haddock_html field for the package using ghc-pkg. -- Carlo Hamalainen http://carlo-hamalainen.net

On Mon, Dec 16, 2013 at 7:54 AM, Carlo Hamalainen < carlo@carlo-hamalainen.net> wrote:
I'm not sure why, but the "source imports" is an empty list, while the "textual imports" gives the implicit Prelude and Data.Maybe. Also the names are the program names like f, s, and main, and don't include things like String, Int, Just, and so on.
"source imports" likely relates to the SOURCE pragma; see http://www.haskell.org/ghc/docs/latest/html/users_guide/separate-compilation... details. I would expect that you get the names *defined* in the module, not those *imported* into it; to get those, you would follow the import lists, as you have already determined. -- brandon s allbery kf8nh sine nomine associates allbery.b@gmail.com ballbery@sinenomine.net unix, openafs, kerberos, infrastructure, xmonad http://sinenomine.net

I'm glad that you've had positive experience with haskell-names.
Here's one caveat: haskell-names cannot use ghc's interface files to get
information about installed modules. Instead, it maintains its own
interface files. Which means that you'll have to install separately all
packages that you need to access using the hs-gen-iface compiler, as
described in the README. Additionally, not all packages that can be
compiled by ghc can be compiled by haskell-names yet.
It's up to you and other ghc-mod users to decide whether this is
acceptable.
Roman
* Carlo Hamalainen
On 14/12/13 15:02, Roman Cheplyaka wrote:
haskell-names can also do this (it's used in halberd to solve a similar task: https://github.com/haskell-suite/halberd)
This is quite useful, thanks.
For the benefit of the list archive, here is what I have worked out so far.
I took the example from http://www.haskell.org/haskellwiki/GHC/As_a_library which uses getNamesInScope (I thought that this was promising). But it returned an empty list for the list of names (variable 'n'). I found out that you have to set the context before the call to getNamesInScope, like so:
https://github.com/carlohamalainen/playground/blob/master/haskell/ghc_symbol...
target <- guessTarget targetFile Nothing setTargets [target] load LoadAllTargets
-- http://stackoverflow.com/questions/11571520/reify-a-module-into-a-record setContext [IIDecl (simpleImportDecl (mkModuleName "B"))]
modSum <- getModSummary $ mkModuleName "B"
For example on this file,
-- B.hs module B where
import Data.Maybe
f :: a -> Maybe a f x = Just x
s = "boo" :: String
main = print "Hello, World!"
we can get the list of names and also the imports:
$ runhaskell A.hs ([B.main, B.f, B.s], [main, B.main, f, B.f, s, B.s], [], [import (implicit) Prelude, import Data.Maybe])
I'm not sure why, but the "source imports" is an empty list, while the "textual imports" gives the implicit Prelude and Data.Maybe. Also the names are the program names like f, s, and main, and don't include things like String, Int, Just, and so on.
Independently of that, I tweaked an example from the haskell-names docs and this lets me see where String comes from, e.g.
https://github.com/carlohamalainen/playground/blob/master/haskell/ghc_symbol...
$ cat B.hs | runhaskell haskell_names_example.hs
Relevant bits:
"Prelude"
SymType {st_origName = OrigName { origPackage = Just (PackageIdentifier { pkgName = PackageName "base"
, pkgVersion = Version {versionBranch = [4,7,0,0]
, versionTags = []}}) , origGName = GName { gModule = "GHC.Base" , gName = "String"}} , st_fixity = Nothing}
"Data.Maybe"
SymConstructor {sv_origName = OrigName { origPackage = Just (PackageIdentifier { pkgName = PackageName "base"
, pkgVersion = Version {versionBranch = [4,7,0,0]
, versionTags = []}}) , origGName = GName { gModule = "Data.Maybe" , gName = "Just"}} , sv_fixity = Nothing , sv_typeName = OrigName { origPackage = Just (PackageIdentifier { pkgName = PackageName "base"
, pkgVersion = Version { versionBranch = [4,7,0,0]
, versionTags = []}})
, origGName = GName { gModule = "Data.Maybe"
, gName = "Maybe"}}}
This is pretty much what I'm after. The first block shows us that String is exported from the Prelude, even though it's defined in GHC.Base. The second block says that the constructor Just is actually exported from Data.Maybe.
So these ought to able to be stitched together: work through the textual imports one at a time until a symbol appears and then find the haddock_html field for the package using ghc-pkg.
-- Carlo Hamalainen http://carlo-hamalainen.net

On 16/12/13 16:01, Roman Cheplyaka wrote:
Here's one caveat: haskell-names cannot use ghc's interface files to get information about installed modules. Instead, it maintains its own interface files. Which means that you'll have to install separately all packages that you need to access using the hs-gen-iface compiler, as described in the README. Additionally, not all packages that can be compiled by ghc can be compiled by haskell-names yet.
It's up to you and other ghc-mod users to decide whether this is acceptable.
So if I use the branch of Cabal [1] then the local database file $HOME/.cabal/share/x86_64-linux-ghc-7.6.3/haskell-names-0.3.2.2/libraries/packages.db will be updated automatically? What packages are currently known to have problems with haskell-names? [1] https://github.com/feuerbach/Cabal Thanks, -- Carlo Hamalainen http://carlo-hamalainen.net

* Carlo Hamalainen
On 16/12/13 16:01, Roman Cheplyaka wrote:
Here's one caveat: haskell-names cannot use ghc's interface files to get information about installed modules. Instead, it maintains its own interface files. Which means that you'll have to install separately all packages that you need to access using the hs-gen-iface compiler, as described in the README. Additionally, not all packages that can be compiled by ghc can be compiled by haskell-names yet.
It's up to you and other ghc-mod users to decide whether this is acceptable.
So if I use the branch of Cabal [1] then the local database file
$HOME/.cabal/share/x86_64-linux-ghc-7.6.3/haskell-names-0.3.2.2/libraries/packages.db
will be updated automatically?
First, no need to use that fork — all patches have been merged into Cabal master at https://github.com/haskell/Cabal. (However, they are not released yet, so you still have to build the git version.) Second, no, installation won't happen automatically. At the moment you have to do that manually, like this: cabal install --haskell-suite -w hs-gen-iface mtl It'd be nice to add a cabal.config option to do that automatically.
What packages are currently known to have problems with haskell-names?
* Packages that use the latest GHC extensions which haven't been added yet to haskell-src-exts * Packages that rely on custom Setup.hs usually have to be patched, because hs-gen-iface cannot compile Setup.hs, obviously If you run into any (other) problems, please report them (or, better yet, investigate them!) Roman

On 16/12/13 13:54, Carlo Hamalainen wrote:
For the benefit of the list archive, here is what I have worked out so far.
And here is what I've worked out since my last email. I learned more about the GHC API, read a bit more about how ghc-mod works, and came up with this prototype: https://github.com/carlohamalainen/ghc-imported-from Here is a screencast showing it in action with my forked version of ghcmod-vim: http://www.youtube.com/watch?v=VVc8uupYJGs (pick 720p otherwise the text is hard to read) -- Carlo Hamalainen http://carlo-hamalainen.net
participants (3)
-
Brandon Allbery
-
Carlo Hamalainen
-
Roman Cheplyaka