Hoogle is a Haskell API search engine, which allows you to search many standard Haskell libraries by either function name, or by approximate type signature.
- Online version: http://haskell.org/hoogle
- Hackage page: http://hackage.haskell.org/cgi-bin/hackage-scripts/package/hoogle
- Darcs repository: http://code.haskell.org/hoogle
- Bug tracker: http://code.google.com/p/ndmitchell/issues/list
- Manual: This page.
- 1 Hoogle Use
- 2 Hoogle Integration Modes
- 3 Developers
- 4 Theoretical Foundations
- 5 Acknowledgements
Hoogle can be used in several ways:
- Online, with the web interface: http://haskell.org/hoogle
- In the Haskell IRC channel, using the Lambdabot plugin, @hoogle and @hoogle+
- With the command line version available on Hackage.
This section describes Hoogle searches, and the flags available from the Hoogle command line tool. The information applies only to Hoogle 4, the next version of Hoogle, and is still being fleshed out.
Before explaining the syntax of searches, we first give a list of example searches with their meaning:
- "map" Search for the text "map"
- "con map" Search for the text "map" and the text "con"
- "a -> a" Search for the type "a -> a"
- ":: a -> a" Search for the type "a -> a"
- "a" Search for the text "a"
- ":: a" Search for the type "a"
- "id :: a -> a" Search for the text "id" and the type "a -> a"
Searches can be either textual (a list of words), or by type (a type signature) or both. A type search may optionally start with a "::" symbol. A search is considered a text search unless it contains a combination of text and symbols, or if it starts with (::). To search for both a type and a name, place a :: between them, for example "undefined :: a"
Searches can be restricted to a particular module with +Module.Name, or to avoid a module with -Module.Name. The command Module.Name.Foo is treated as +Module.Name Foo.
Searches can be restricted to a particular package with +packagename, or to avoid a package with -package. By default Hoogle will search a standard set of packages.
Command Line Search Flags
Flags can be specified as --flag or /flag. Flags requiring arguments are specified as --flag=arg or /flag=arg. Anything which is not a flag is counted as a search query. Because a console will treat -> as a redirection, you can do -# to get the right character.
- --version Print out version information
- --help Show help on the command line flags
- --include=dir Specify which directories are searched for necessary files, defaults to "." and the data directory configured with Cabal.
- --color Show color output, requires an ANSI compliant terminal, defaults to false
- --count=int Maximum number of results to print, defaults to showing all results
- --start=int 1-based index of first result to print, defaults to 1
- --info Show extended information for the first results
Hoogle has both binary databases (extension .hoo) and textual databases (extension .txt). Textual database files are a list of functions and their types, along with information about type synonyms, instances etc. The textual database files can be generated by Haddock with the --hoogle flag. Support for this is now in Cabal with runhaskell Setup haddock --hoogle.
A more detailed tutorial style style post on database creation is available on the author's blog.
Converting text databases to binary databases
A text database can be converted to a binary database with the command hoogle --convert=file.txt. Any package dependencies should be specified with +package or --data=package.hoo, and will require the binary databases for those packages. The output file can be controlled with --output=file.hoo.
Merging binary databases
Multiple binary databases can be merged with hoogle --combine=file1.hoo --combine=file2.hoo. As before, --output=default.hoo can be specified.
Scope of Web Searches
Using the standard web interface, Hoogle searches: array, arrows, base, bytestring, Cabal, cgi, containers, directory, filepath, haskell-src, HUnit, mtl, old-locale, old-time, packedstring, parallel, parsec, pretty, process, QuickCheck, random, stm, template-haskell, time, xhtml.
Using the Gtk2hs Hoogle, Hoogle searches only in the Gtk2hs package.
,f (ArgNone Web) ["w","web"] [PCmdLine] "Run as though it was a CGI script" ,f (ArgNone Test) ["test"] [PCmdLine] "Run the regression tests" ,f (ArgStr Dump) ["dump"] [PCmdLine] "Dump a database for debugging" ,f (ArgFileIn DataFile ["hoo"]) ["d","data"] [PCmdLine,PMultiple] "Database file" ,f (ArgNone Verbose) ["v","verbose"] [PCmdLine] "Display verbose information" ,f (ArgNone Debug) ["debug"] [PCmdLine] "Debugging only" ,f (ArgFileIn TestFile ["txt"]) ["testfile"] [PCmdLine,PMultiple] "Run tests from a file" ,f (ArgFileIn Rank ["txt"]) ["rank"] [PCmdLine,PMultiple] "Generate ranking scores"
Hoogle Integration Modes
Hoogle can be integrated with various programs, listed below. Most of these integration modes were contributed by users, and users are encouraged to add more programs to this list.
From the search bar: Go to the Hoogle website in Firefox and click on "Search plugin", top right hand corner. This will add a Hoogle entry to the search box in Firefox.
As a keyword search: You can set up Hoogle as a keyword search in Firefox. This means that you can type h map directly into the location bar and you'll jump directly to the Hoogle search results page.
- Visit Hoogle's web interface: http://haskell.org/hoogle
- Right-click on the text input box and click "Add a Keyword for this Search..."
- Give it a nice short keyword like "h".
Ever feel like having access to hoogle whilst messing around in GHCi? It's relatively easy to integrate the two. I'm on Linux, so I don't know how well the following will work if you're on Windows.
The following will install hoogle as a shell command, and configure GHCi to have a command ":hoogle":
- cabal install hoogle
- echo >> ~/.ghci ':def hoogle \x -> return $ ":!hoogle \"" ++ x ++ "\""'
NB. the above wraps the argument in quotes before passing to the shell command, so there is no need to supply quotes; eg.
:hoogle map :hoogle (a -> b) -> [a] -> [b]
Installation from source (without cabal)
First, you need to download and compile Hoogle. Then, we want to move hoogle to somewhere in your system's
$PATH (open a terminal and type
echo $PATH to see where this is). I suggest ~/bin, although you might want to go for /usr/bin or /usr/local/bin, etc.
Copy the Hoogle binary and hoogle.txt to the directory you chose. If you're using a version of hoogle pulled straight from darcs, you can ignore everything up until the 'Next, we need to integrate it into GHCi' bit. Otherwise:
There's a problem in that hoogle doesn't look for hoogle.txt in the system
$PATH, it only looks in the current directory. This is a slight pain but is easily worked around: rename the hoogle binary to hoogle-bin, then create a new text file called 'hoogle' with the following contents:
#! /bin/bash hoogle-bin -l /path/to/your/chosen/directory/hoogle.txt "$@"
chmod hoogle to make it executable (try
chmod +x hoogle). Now you should be able to run hoogle requests from the shell. Try a few of the examples above.
How it works
Next, we need to integrate it into GHCi. We can execute shell commands with GHCi via
:def. Load up GHCi, and type the following:
:def hoogle \x -> return $ ":!hoogle " ++ x
If this executes cleanly, you should be able to run hoogle commands from GHCi via
:hoogle map or
:hoogle "(a -> b) -> [a] -> [b]". Be careful: you need the extra quotes when hoogling types, at least on my system.
:ho works as an abbreviation of
:h clashes with
Finally, we want to make this persist across GHCi sessions. GHCi loads a file called ~/.ghci before running, so simply stick the above
:def in that file and all should work.
Contributed by DavidHouse
haskell-mode from versions 2.4 onwards have the function haskell-hoogle, which will hoogle the identifier at point. Setup:
(require 'haskell-mode) (define-key haskell-mode-map "\C-ch" 'haskell-hoogle) ;(setq haskell-hoogle-command "hoogle")
You will need a web browser configured for best results. Here's an example setup for Safari:
(setq browse-url-browser-function 'browse-url-safari) (defun browse-url-safari (url &optional new-window) "Open URL in a new Safari window." (interactive (browse-url-interactive-arg "URL: ")) (unless (string= "" (shell-command-to-string (concat "open -a Safari " url))) (message "Starting Safari...") (start-process (concat "open -a Safari " url) nil "open -a Safari " url) (message "Starting Safari... done")))
Alternately, you can build the command-line hoogle (darcs repo below) and uncomment the third line above, then results will appear in a buffer.
Firefox Ubiquity Integration
Ubiquity provides a graphical command-line for Firefox. To install Ubiquity, see the tutorial.
To install the Ubiquity Hoogle command, visit the command's home page and click Subscribe... when asked whether you want to install it. You may also want to look at the introductory article.
This work is licensed under the GPL version 2.0. By submitting any patches to Hoogle you agree to license them under the BSD license, or to assign copyright to Neil Mitchell who will include them under the GPL (either one, your choice). This is so I can relicense Hoogle under the BSD at a later date if that proves beneficial to the Haskell community.
The work is intended to be helpful, open and free. If the license doesn't meet your needs then talk to me.
The Source Code
$ darcs get http://code.haskell.org/hoogle/
Contributions are most welcome. Hoogle is written in Haskell 98 + Heirarchical Modules, I do not wish to change this. Other than that, I'm pretty flexible about most aspects of Hoogle. The bug tracker has many outstanding tasks, but please contact me if you have thoughts on doing something major to Hoogle, so I can give some advice.
A lot of related work was done by Rittri  and Runciman  in the late 80's. Since then Di Cosmo  has produced a book on type isomorphisms, which is also related. Unfortunately the implementations that accompanied the earlier works were for functional languages that have since become less popular, and to my knowledge no existing functional programming language has a tool such as Hoogle.
- Mikael Rittri, Using Types as Search Keys in Function Libraries. Proceedings of the fourth international conference on Functional programming languages and computer architecture: 174-183, June 1989. (http://portal.acm.org/citation.cfm?id=99384)
- Colin Runciman and Ian Toyn, Retrieving reusable software components by polymorphic type. Journal of Functional Programming 1 (2): 191-211, April 1991. (http://portal.acm.org/citation.cfm?id=99383)
- Roberto Di Cosmo. Isomorphisms of types: from lambda-calculus to information retrieval and language design. Birkhauser, 1995. ISBN-0-8176-3763-X (http://www.pps.jussieu.fr/~dicosmo/Publications/ISObook.html)
I have given two presentations on type searching in Hoogle:
- December 2005, York University - information on Hoogle type searching in versions 1 to 3.
- August 2008, AngloHaskell - information on type searching in versions 1 to 4. Audio is also available from that link.
I didn't know of any similar tools before starting development, and no other tool has really influenced this tool (except the first on this list). The follow are provided for comparison.
- Google - Google rock!
- Hayoo - Similar to Hoogle, but with less focus on type search
- Krugle - Search code, no Haskell :(
The code is all © Neil Mitchell 2004-2008. The initial version was done in my own time, and further refinement and reimplementation was done as part of my PhD. During Summer 2008 I was funded to full-time on Hoogle by Google Summer of Code with the haskell.org mentoring organisation. Various people have given lots of useful ideas, including my supervisor Colin Runciman, and various members of the Plasma group. In addition the following people have also contributed some code or significant debugging work:
- Thomas "Bob" Davie
- Don Stewart
- Thomas Jäger
- Gaal Yahas
- Mike Dodds
- Niklas Broberg
- Esa Ilari Vuokko
- Udo Stenzel
- Henk-Jan van Tuyl
- Gwern Branwen
- Tillmann Rendel
- David Waern
- Ganesh Sittampalam
- Duncan Coutts
- Peter Collingbourne
- Andrea Vezzosi
In previous versions, all the data was taken from Zvon's Haskell Guide. Thanks to their open and friendly policy of allowing the data to be reused, this project became possible. More recent versions use the Hierarchical Libraries as distributed with GHC, and databases generated by Haddock.