Where can I find the source code of packages/modules? - haskell

I would like to look at the code of functions defined in modules, such as Data.List or Data.Map.
I can import Data.List module with
import Data.List
and then I can use the functions nub or sort.
I would like to know where I can find these functions to look at their code.
In which directory are the modules installed by default?
PS: Windows 8.1, I installed Haskell Platform.

That directory contains compiled modules, so you wouldn't be able to read the source there.
What you can do is to find your function in online documentation and then click "Source" on the right.

As #arrowd notes in his answer,
That directory contains compiled modules, so you wouldn't be able to
read the source there.
The GHC repo (and its Github mirror) can be directly browsed, but there is an easier way:
Use Hoogle or Stackage to find the package where the module/function resides
Note that Hoogle and Stackage are case-sensitive. (It's best to look up modules with their capitalized names.)
A query for sort in Hoogle yields a list similar to the one below. Stackage has a slightly different style, but the basics are the same (mostly because it uses Hoogle for lookup). The lines in green under the result headings show the name(s) of the containing
(1) package(s) (in small caps) and
(2) module(s) (capitalized).
There can be multiple functions with the same name, but the module and package name helps to choose the right one.
Click on the function/module name
Click on "#Source"

Related

Find which module imported another module

I need to find out why some module gets included into compilation.
There is some class that should not be included and I think there are some unused imports or bad architecture that requires unnecessary imports. Is there a way to find which modules import some module, which modules import these modules that include this module, and so on, tracking that down to main class of application?
You could use -D dump-dependencies for this, in which case the compiler will generate two files that can be used to follow the dependency graph in both directions:
dump/<target>/.dependants.dump
dump/<target>/.dependencies.dump
There is also a handy online tool created by Mark Knol that helps a lot with analyzing these files. To answer the question "what does Array depend on?", you can just upload the two files and enter "array" into the search field:
Conveniently, the results are also clickable.
I've just came up with very simple idea: just delete this file and there will be compilation errors in places where this module is imported.

Running Hoogle Locally

I want to run hoogle on a project of mine. I successfully generated the hoogle database (a file with .hoo extension) from my project.
But when I run the server locally, hoogle cannot find any of the functions or types that are defined in my project.
It can find some of the prelude functions such as map, but none of the functions that are defined in my project.
hoogle dump my-project.hoo dumps the content with no error.
I also moved my-project.hoo to ~/.cabal/share/x86_64-osx-ghc-7.8.4/hoogle-4.2.38/databases where all the .hoo files reside. No success again.
-verbose switch also does not output any useful information.
Any suggestion is appreciated.
Edit:
Thanks to mhuesch's suggestion, I was able to get the search results. Although, the returned results are not linked to the local hackage documents. Something that I couldn't find anywhere on the web is that the hoogle server looks for a file called default.hoo in the current directory.
Edit 2:
If you, like me, have 5000+ databases (i.e., .hoo files) you may get a "too many open files" error when combining them. The trick is simple: run hoogle combine x*.hoo -o=parts/x.hoo for all x='a' ... 'z' and then run hoogle combine *.hoo -o=default.hoo in the parts folder.
Edit 3:
If you want to link your hoogle search results with local hackage documentation,
use hoogle convert --doc='absolute-path-to-your-doc' your-package-hoogle-doc.txt default.hoo.
I couldn't get relative path working.
Hoogle searches the current directory (where the command hoogle is run) for a database called 'default.hoo', so if you rename your database to that it should find it.
To add it to the database in your cabal directory, I believe this should work (taken from http://newartisans.com/2012/09/running-a-fully-local-hoogle/):
cd {...path to hoogle databases dir...}
mv default.hoo default.hoo-prev
hoogle combine *.hoo
Edit: (in response on Oxy's edits)
My knowledge of default.hoo comes from here. It seems to doesn't seem to be very well know.
hoobuddy (the above linked project), while cool, doesn't seem to address what you want. I think the key to that is in the help of hoogle data
$ hoogle data --help
...
-l --local[=FILEPATH] Use local documentation if available
...
I haven't done it myself so I am not sure. The author of this writeup achieved local documentation linking by compiling hoogle from source and adding his local docs directory. I think that you can avoid that by using hoogle data.

Haddock - link to function in external module (whole module imported)

Suppose I have a Haskell module named MyModule that imports an external module like this:
import ModuleA hiding (a, b, c)
And I cannot modify this import statement, because the program is not exactly mine.
I wish to link to ModuleA.external_function in the documentation for ModuleA, in the comments above a function called my_function. So the code looks something like this:
-- | my_function makes use of 'ModuleA.external_function'
my_function :: Int -> Int
Using haddock 2.10.0, and running cabal haddock, the link to ModuleA.external_function is generated as dist/doc/html/MyModule/ModuleA.html#v:external_function . However, the problem is that the dist/doc/html/MyModule/ModuleA.html file does not exist.
How can I generate a link to the docs for ModuleA instead, like module-A-package/docs/ModuleA.html#v:external_function. In other words, something similar to what http://hackage.haskell.org/package/text-0.11.2.0/docs/Data-Text.html has for its links to the String type (they link to http://hackage.haskell.org/package/base-4.5.0.0/docs/Data-String.html#t:String)? Bear in mind that I cannot modify the import statement.
Thank you.
To make links to external packages in the Haddock documentation, you need to instruct it where to find the documentation for those packages.
It is done by using the --read-interface Haddock command-line option.
Using your example, it will be :
haddock --read-interface module-A-package/docs/,module-A-package/docs/module-A-package.haddock
The .haddock file is made when generating documentation for the package module-A-package using ----dump-interface Haddock command-line option.
More information can be found on the Haddock documentation or this HaskellWiki page.

Haskell skeleton template project for beginners

I have 3 data constructors say A,B and C that are defined in files A.hs, B.hs, C.hs and the files are in the directory project-utils.
Now I want to use these data constructors in parts of other projects. These projects reside in totally different directories.
How do I import the data and type constructors of A, B and C in such project files?
Thanks to the first answer given below, I realized that I am looking for a skeleton to organize such project in a better way. I searched but could not find any such project skeleton.
The link provided there contains many things that are described in vague manner. For example, on line 5 there it is simple written as "..."
What i am looking for is,
The skeleton project should not be very simple "single" file project as is given on the Haskell site. But should NOT be overly complex with tons of dependencies etc that we see in many projects on hackage.
Edit: I changed the title to reflect my problem in a better way. Sorry for the inconvenience.
Make a cabal pkg out of them and install that package locally.
Follow a directory stucture as here and use those constuctors in a project rather than across projects. The stucture mentioned is basically a structure of a cabal package.
Manually add the input source while compiling through ghc or loading in ghci.
Example
ghci -i project-utils/A.hs Foo.hs
where Foo.hs uses elements exported by A.hs
May not be exactly what you're looking for, but for future readers of this question, a Haskell skeleton/template project was just released here:
https://github.com/tfausak/haskeleton
It does add some dependencies like hlint and hspec. Here is the blog post, which goes through each of the individual decisions:
http://taylor.fausak.me/2014/03/04/haskeleton-a-haskell-project-skeleton/
I found this: how to write a haskell program link as a handy reference.
#Tem Pora : you need to install yesod and yesod-bin. This link talks more about the scaffolding
cabal install yesod
cabal install yesod-bin
<cdtoprojdir> yesod init
Hope this helps.

Importing Haskell modules

I'm new to Haskell. How come when I try to use Days from Data.Time I get this error:
Could not find module `Data.Time':
It is a member of the hidden package `time-1.1.4'.
Perhaps you need to add `time' to the build-depends in your .cabal file.
I am importing Data.List and Control.Monad, and neither gives me this error message, but the code import Data.Time does.
What am I missing?
Thanks for the help!
EDIT: I'm getting a similar error message when I use: import Directory
Thanks guys, your answers got me on track!
Fire up Leksah with this project, open the package menu and select "edit package" from it. Now, choose "dependencies" and add the dependency you need (in your case time). You may also choose a version.
PS: Don't forget to hit the "save" button afterwards. (I think this is a design failure...).
Just edit the projects .cabal file, usually in the top directory named ProjectName.cabal and find the line(s) with "build-depends:" and add "time" to this list. No need for Leksah, unless you already use it.
EDIT: To answer your question of "why now and not with module X"
Data.Time is in the time package, which evidently isn't included in your build dependencies. Similar story for the Directory module. You don't get these errors with Data.List or Control.Monad because they are part of the base package which I'll bet is in your build-deps.
On a side note, it is worth taking time to learn what modules are in base and what functionality those modules provide. Base is rather large and very useful.

Resources