Difference between revisions of "Hoogle"

From HaskellWiki
Jump to navigation Jump to search
(hoogle 5 is the newest version)
 
(64 intermediate revisions by 20 users not shown)
Line 1: Line 1:
To use hoogle go to http://haskell.org/hoogle. Hoogle is a Haskell API search engine, written by [[User:NeilMitchell|Neil Mitchell]]. It allows you to search by either name, or by approximate type signature.
+
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
* '''Beginners:''' See the [[/Tutorial|Tutorial]]
 
  +
* '''Hackage page:''' http://hackage.haskell.org/cgi-bin/hackage-scripts/package/hoogle
* '''Advanced:''' Report a [[/Bugs|Bug]], see the [[/Specs|Technical Specifications]]
 
  +
* '''GitHub repository:''' https://github.com/ndmitchell/hoogle
* Read on for the '''Manual'''
 
* '''Mailing list:''' [http://www.haskell.org/mailman/listinfo/hoogle Subscribe and Archives]
+
* '''Darcs repository:''' http://code.haskell.org/hoogle
  +
* '''Bug tracker:''' http://code.google.com/p/ndmitchell/issues/list
  +
* '''Manual:''' https://github.com/ndmitchell/hoogle/blob/master/README.md
   
  +
Below is the old manual, which is gradually being phased out.
== How to use Hoogle ==
 
   
This section details how to use the Hoogle program, it is more than just a command line tool or a website.
 
   
  +
== Hoogle Use ==
* The web interface: http://haskell.org/hoogle
 
* Via the Haskell [[IRC channel]], using the [[Lambdabot]] plugin, <tt>@hoogle</tt> and <tt>@hoogle+</tt>
 
* Download the source with Darcs ([http://www.cs.york.ac.uk/fp/darcs/hoogle/ http://www.cs.york.ac.uk/fp/darcs/hoogle/])
 
* Download a command line version (yet to be released, but get the source and compile it yourself)
 
* Hoogle is distributed with [[Lambdabot]]. Build a local [[Lambdabot]], and use its command line interface
 
   
  +
Hoogle can be used in several ways:
=== Using Hoogle from Firefox ===
 
   
  +
* Online, with the web interface: http://haskell.org/hoogle
'''From the search bar:''' Go to the [http://haskell.org/hoogle/ Hoogle website] in Firefox and click on Firefox Plugin, top right hand corner. This will add a Hoogle entry to the search box in Firefox.
 
  +
* In the [[IRC channel|Haskell IRC channel]], using the [[Lambdabot]] plugin, <tt>@hoogle</tt> and <tt>@hoogle+</tt>
  +
* With the command line version [http://hackage.haskell.org/cgi-bin/hackage-scripts/package/hoogle 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 and is still being fleshed out.
'''As a keyword search:''' You can set up Hoogle as a keyword search in Firefox. This means that you can type <tt>h map</tt> directly into the location bar and you'll jump directly to the Hoogle search results page.
 
   
  +
=== Searches ===
# 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".
 
   
  +
Before explaining the syntax of searches, we first give a list of example searches with their meaning:
In the future some of these will be available for IE as well.
 
   
  +
* "map" Search for the text "map"
=== Using Hoogle from GHCi ===
 
  +
* "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"
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.
 
   
  +
'''Modules:'''
First, you need to download and compile Hoogle. Then, we want to move hoogle to somewhere in your system's <code>$PATH</code> (open a terminal and type <code>echo $PATH</code> to see where this is). I suggest ~/bin, although you might want to go for /usr/bin or /usr/local/bin, etc.
 
  +
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.
   
  +
'''Packages:'''
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:
 
  +
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 ====
There's a problem in that hoogle doesn't look for hoogle.txt in the system <code>$PATH</code>, 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:
 
   
  +
Flags can be specified as <tt>--flag</tt> or <tt>/flag</tt>. Flags requiring arguments are specified as <tt>--flag=arg</tt> or <tt>/flag=arg</tt>. Anything which is not a flag is counted as a search query. Because a console will treat <tt>-></tt> as a redirection, you can do <tt>-#</tt> to get the right character.
#! /bin/bash
 
hoogle-bin -l /path/to/your/chosen/directory/hoogle.txt "$@"
 
   
  +
* <tt>-V, --version</tt> Print out version information
chmod hoogle to make it executable (try <code>chmod +x hoogle</code>). Now you should be able to run hoogle requests from the shell. Try a few of the examples above.
 
  +
* <tt>-?, --help</tt> Show help on the command line flags
  +
* <tt>-v --verbose</tt> Verbose mode
  +
* <tt>--color</tt> Show color output, requires an ANSI compliant terminal, defaults to false
  +
* <tt>--count=int</tt> Maximum number of results to print, defaults to showing all results
  +
* <tt>--start=int</tt> 1-based index of first result to print, defaults to 1
  +
* <tt>--info</tt> Show extended information for the first results
   
  +
=== Database Creation ===
Next, we need to integrate it into GHCi. We can execute shell commands with GHCi via <code>:def</code>. Load up GHCi, and type the following:
 
   
  +
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 [http://haskell.org/haddock/ Haddock] with the <tt>--hoogle</tt> flag. Support for this is now in [http://haskell.org/cabal/ Cabal] with <tt>runhaskell Setup haddock --hoogle</tt>.
:def hoogle \x -> return $ ":!hoogle " ++ x
 
   
  +
A more detailed tutorial style style post on database creation is available [http://neilmitchell.blogspot.com/2008/08/hoogle-database-generation.html on the author's blog].
If this executes cleanly, you should be able to run hoogle commands from GHCi via <code>:hoogle</code>, i.e. <code>:hoogle map</code> or <code>:hoogle "(a -> b) -> [a] -> [b]"</code>. Be careful: you need the extra quotes when hoogling types, at least on my system. <code>:ho</code> works as an abbreviation of <code>:hoogle</code> (just <code>:h</code> clashes with <code>:help</code>).
 
   
  +
You can create some default databases with (Windows users, please read [http://stackoverflow.com/questions/7523151/hoogle-data-on-windows Hoogle data on Windows] first):
Finally, we want to make this persist across GHCi sessions. GHCi loads a file called ~/.ghci before running, so simply stick the above <code>:def</code> in that file and all should work.
 
   
  +
$ hoogle data
Contributed by [[User:DavidHouse|DavidHouse]]
 
   
  +
or you can create an extended database with
=== Using Hoogle from Vim ===
 
   
  +
$ hoogle data all
Hoogle can be called from Vim via the lambdabot vim scripts.
 
* Download and build [[Lambdabot]], which will also build a Hoogle.
 
* Install the scripts/vim programs into your path
 
   
  +
==== Converting text databases to binary databases ====
Then, to invoke hoogle from vim, passing the current buffer line or
 
region as input:
 
!!bot hoogle
 
   
  +
A text database can be converted to a binary database with the command <tt>hoogle convert file.txt</tt>. Any package dependencies should be specified with <tt>+package</tt> or <tt>--data=package.hoo</tt>, and will require the binary databases for those packages. The output file can be controlled with <tt>--output=file.hoo</tt>.
For example, if the buffer contains the line:
 
map
 
Running !!bot hoogle will replace that with:
 
Prelude.map :: (a -> b) -> [a] -> [b]
 
Data.IntMap.map :: (a -> b) -> IntMap a -> IntMap b
 
Data.IntSet.map :: (Int -> Int) -> IntSet -> IntSet
 
   
  +
==== Merging binary databases ====
If the buffer contains:
 
(a,b) -> b
 
Running !!bot hoogle will replace that with:
 
Prelude.snd :: (a, b) -> b
 
Prelude.uncurry :: (a -> b -> c) -> (a, b) -> c
 
Prelude.fst :: (a, b) -> a
 
   
  +
Multiple binary databases can be merged with <tt>hoogle combine file1.hoo file2.hoo</tt>. The result would be written as <tt>default.hoo</tt>. As before, <tt>--output=out.hoo</tt> can be specified.
=== Using Hoogle from Emacs ===
 
Never to be outdone, here's a quick tip for using Hoogle from Emacs in case anyone hadn't already spotted it:
 
   
  +
The following script (from Matt Brown) may be helpful:
M-! runs the command shell-command
 
   
  +
$cat hoogleCombiner.sh
It's as simple as M-! hoogle whatever RET. If you ''really'' want to save the six keystrokes it takes to type 'hoogle' (and lets face it, which Emacsians don't?), grab [[Haskell mode for Emacs/Hoogle.el |Hoogle.el]] and stick the following in your .emacs:
 
  +
#!/bin/bash
  +
  +
function combines {
  +
for f in ~/.hoogle/*.hoo
  +
do
  +
echo -n " $(readlink -f $f)"
  +
done
  +
}
  +
  +
hoogle --output=$(readlink -f ~/.hoogle.hoo) combine $(combines)
   
  +
Simon Michaels suggests:
(require 'hoogle)
 
(global-set-key (kbd "C-c h") 'hoogle-lookup)
 
   
  +
#!/bin/bash
Of course, change the shortcut to suit your needs. For more information, check out the docstring of hoogle-lookup.
 
  +
#
  +
# Search for hoogle databases in or under the directories/files specified
  +
# as arguments or hard-coded below (see allHoogleDbs), and combine them as
  +
# ~/.hoogle/default.hoo. Lets you search all your code (and installed
  +
# haskell libs) at once.
  +
#
  +
# Usage:
  +
# $ hoogle-update-db
  +
# $ alias hoogle="hoogle --i=$HOME/.hoogle"
  +
# $ hoogle something
  +
  +
# nb current hoogle cli quirks: path options should have two hyphens, one
  +
# equals, and no tildes, eg: --d=NOTILDEFILEPATH
  +
  +
#set -x
  +
  +
ARGS=$*
   
  +
function allHoogleDbs {
== Hoogle databases ==
 
  +
for p in $ARGS ~/src/ ~/.cabal/share/ # add paths here
  +
do
  +
echo -n " $(findHoogleDbs $p)"
  +
done
  +
}
  +
  +
function findHoogleDbs {
  +
find $1 -name '*.hoo'
  +
}
   
  +
function combineOpts {
A Hoogle database has a list of functions and their types, they are plain text files. There are several approaches for generating Hoogle databases. Hoogle databases have the property that combining the files will still produce a valid database. In general there should be no reason for a user to create a Hoogle database.
 
  +
for f in $*
  +
do
  +
echo -n " $(readlink -f $f)"
  +
done
  +
}
   
  +
dbs=$(allHoogleDbs)
=== Haddock ===
 
  +
echo Found $dbs
  +
mkdir -p ~/.hoogle
  +
hoogle --output=$(readlink -f ~/.hoogle/default.hoo) combine $(combineOpts $dbs)
  +
echo Created ~/.hoogle/default.hoo
   
  +
==== Installing databases from Hackage ====
The HEAD version of Haddock has a --hoogle flag which will generate a hoogle database. This is the prefered method of generating databases. The HEAD version of Cabal now supports haddock --hoogle, which is the easiest method of documenting a large library.
 
   
  +
Packages on Hackage usually have .txt databases generated for you, so you can download those. You can find them in the <tt>html</tt> directories under the name <tt>[package-name].txt</tt>. So, for example, for <tt>diagrams-core</tt> the database can be found here: http://hackage.haskell.org/packages/archive/diagrams-core/0.6.0.2/doc/html/diagrams-core.txt
=== hadhtml ===
 
   
  +
==== Scope of Web Searches ====
First make Haddock documentation for your system, then run hadhtml on the directory containing the HTML. The Hoogle database distribute with Hoogle was generated with hadhtml.
 
   
  +
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.
=== hihoo ===
 
   
  +
Using the [http://haskell.org/hoogle/?hoogle=gtk+%2bpackage Gtk2hs Hoogle], Hoogle searches only in the Gtk2hs package.
This approach uses the .hi files generated by GHC, so has the potential for being most accurate, but is currently unsupported and does not work in lots of cases.
 
   
== Road Map ==
+
=== Developer Flags ===
   
  +
,f (ArgNone Web) ["w","web"] [PCmdLine] "Run as though it was a CGI script"
These are the future tasks, including fixing the remaining [[/Bugs]].
 
  +
,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 ==
=== Admin ===
 
   
  +
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.
* get XHoogle in the repo
 
* Move the bugs into the ndmitchell bug tracker
 
   
=== Short Term ===
+
=== Firefox Integration ===
   
  +
'''From the search bar:''' Go to the [http://haskell.org/hoogle/ Hoogle website] in Firefox and click on "Search plugin", top right hand corner (some versions of firefox instead will have an "add Hoogle" option in the list of search engines when you are viewing the Hoogle page). This will add a Hoogle entry to the search box in Firefox.
i.e. before Hoogle3 goes public
 
   
  +
'''As a keyword search:''' You can set up Hoogle as a keyword search in Firefox. This means that you can type <tt>h map</tt> directly into the location bar and you'll jump directly to the Hoogle search results page.
* Fix parse errors, ) ->, ) ->@ , func :: With Type
 
* Regression tests for hoogle
 
* You cannot search for certain keywords, i.e. @, because it is not a recognised lex symbol
 
* Add comment characters, --, {- and -} to the list of symbols.
 
* Put back more detailed information about the Prelude functions, see LibraryDocumentation.
 
* Prelude.Either :: data Either a b -- the :: is entirely wrong
 
** Prelude.Either data Either a b -- website
 
** data Prelude.Either a b -- command line
 
   
  +
# Visit Hoogle's web interface: http://haskell.org/hoogle
=== Medium Term ===
 
  +
# Right-click on the text input box and click "Add a Keyword for this Search..."
  +
# Give it a nice short keyword like "h".
   
  +
If you want to also search for special symbols in Firefox keyword search, modify the keyword search URL to be: <tt>javascript:window.location.href="http://haskell.org/hoogle?q=" + encodeURIComponent("%s")</tt>
* Parameterise out by package, i.e. split off OpenGL
 
* Compile with [[Yhc]] and distribute
 
* Write GTK front end
 
* Multiword search? power set
 
* Dehack the Score program
 
* Multiparameter type classes
 
   
=== Long Term ===
+
=== Chrome Integration ===
   
  +
'''Add to list of available search engines:''' Exactly as for the search bar in Firefox above.
* Integration with [[Cabal]]
 
* Integration with http://darcs.augustsson.net/Darcs/Djinn
 
* Other languages than just Haskell, Clean etc.
 
   
  +
'''As a keyword search:''' Under Chrome Preferences (Basic),
=== Hoogle Suggest ===
 
  +
select Manage Search Engines. You can then edit the keyword box appropriately.
   
  +
To get the new Hoogle engine into the "default" section from the "other" section, make it default, and then re-select what was the original default.
* People often type to, instead of ->
 
  +
* Numeric literals
 
  +
(Works with Chrome on Mac OS X, at least).
* Concepts? tuple, random, monads etc.
 
  +
* Wrongly suggests capitals for t1 etc.
 
  +
=== GHCi Integration ===
* Kind errors, Maybe -> Bool, suggest Maybe a -> Bool
 
  +
* Return hits for module names ("Data" should return at least the module Data, probably known submodules as well)
 
  +
Ever feel like having access to hoogle whilst messing around in GHCi? It's relatively easy to integrate the two.
* People sometimes make typographical errors. Use a levenshtein distance edit on searches that have no result, to try to guess approximate answers by name (a la lambdabot's editing correction, here: http://www.cse.unsw.edu.au/~dons/code/lambdabot/Lib/Util.hs)
 
  +
  +
The following will install hoogle as a shell command, and configure GHCi to have commands ":hoogle" showing all matches, and ":doc" showing haddock documentation for the first match:
  +
  +
# <tt>cabal install hoogle</tt>
  +
# <tt>echo >> ~/.ghci ':def hoogle \x -> return $ ":!hoogle \"" ++ x ++ "\""'</tt>
  +
# <tt>echo >> ~/.ghci ':def doc \x -> return $ ":!hoogle --info \"" ++ x ++ "\""'</tt>
  +
  +
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]
  +
  +
Done!
  +
  +
On Windows you should add the same lines
  +
:def hoogle \x -> return $ ":!hoogle \"" ++ x ++ "\""
  +
:def doc \x -> return $ ":!hoogle --info \"" ++ x ++ "\""
  +
to file (XP/2003):
  +
C:\Documents and Settings\[your windows account]\Application Data\ghc\ghci.conf
  +
or(Windows Vista/7):
  +
C:\users\[your windows account]\Application Data\ghc\ghci.conf
  +
  +
  +
==== 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 <code>$PATH</code> (open a terminal and type <code>echo $PATH</code> 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 <code>$PATH</code>, 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 <code>chmod +x hoogle</code>). 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 <code>:def</code>. 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 <code>:hoogle</code>, i.e. <code>:hoogle map</code> or <code>:hoogle "(a -> b) -> [a] -> [b]"</code>. Be careful: you need the extra quotes when hoogling types, at least on my system. <code>:ho</code> works as an abbreviation of <code>:hoogle</code> (just <code>:h</code> clashes with <code>:help</code>).
  +
  +
Finally, we want to make this persist across GHCi sessions. GHCi loads a file called ~/.ghci before running, so simply stick the above <code>:def</code> in that file and all should work.
  +
  +
Contributed by [[User:DavidHouse|DavidHouse]]
  +
  +
=== Emacs Integration ===
  +
[[Haskell_mode_for_Emacs|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 ===
  +
  +
[https://wiki.mozilla.org/Labs/Ubiquity Ubiquity] provides a graphical command-line for Firefox. To install Ubiquity, see the [https://wiki.mozilla.org/Labs/Ubiquity/Ubiquity_0.1_User_Tutorial tutorial].
  +
  +
To install the Ubiquity Hoogle command, visit the [http://www.randomhacks.net/git/ubiquity/hoogle/ command's home page] and click <b>Subscribe...</b> when asked whether you want to install it. You may also want to look at the [http://www.randomhacks.net/articles/2008/09/01/ubiquitous-hoogle introductory article].
   
 
== Developers ==
 
== Developers ==
   
This work is licensed under the [http://www.gnu.org/copyleft/gpl.html 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 prooves beneficial to the Haskell community.
+
This work is licensed under the [http://www.gnu.org/copyleft/gpl.html 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 work is intended to be helpful, open and free. If the license doesn't meet your needs then talk to me.
 
Hoogle depends on [http://www.cs.chalmers.se/~d00nibro/haskell-src-exts/ Haskell Source eXtensions].
 
   
 
=== The Source Code ===
 
=== The Source Code ===
   
darcs get http://www.cs.york.ac.uk/fp/darcs/hoogle
+
<tt>$ darcs get http://code.haskell.org/hoogle/</tt>
   
  +
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 [http://code.google.com/p/ndmitchell/issues/list 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.
[http://haskell.org/hoogle/haddock/ Haddock generated documentation], [http://www-users.cs.york.ac.uk/~malcolm/cgi-bin/darcsweb.cgi?r=hoogle;a=summary Darcsweb of 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. Some projects could be easily embarked upon are profiling, writing test frameworks and new front ends. Contact me if you have thoughts on doing something to Hoogle.
 
   
 
== Theoretical Foundations ==
 
== Theoretical Foundations ==
   
 
A lot of related work was done by Rittri [1] and Runciman [2] in the late 80's. Since then Di Cosmo [3] 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.
 
A lot of related work was done by Rittri [1] and Runciman [2] in the late 80's. Since then Di Cosmo [3] 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.
 
There is also a [http://www-users.cs.york.ac.uk/~ndm/downloads/slides-hoogle-08_dec_2005.pdf presentation] on Hoogle that I gave, which has some details of the theory.
 
   
 
# 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)
 
# 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)
 
# 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)
 
# 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:
  +
  +
* [http://www-users.cs.york.ac.uk/~ndm/downloads/slides-hoogle-08_dec_2005.pdf December 2005, York University] - information on Hoogle type searching in versions 1 to 3.
  +
* [http://www.wellquite.org/anglohaskell2008/ August 2008, AngloHaskell] - information on type searching in versions 1 to 4. Audio is also available from that link.
   
 
=== Similar Tools ===
 
=== Similar Tools ===
Line 183: Line 292:
   
 
* [http://www.google.com/ Google] - Google rock!
 
* [http://www.google.com/ Google] - Google rock!
  +
* [http://holumbus.fh-wedel.de/hayoo/hayoo.html Hayoo] - Similar to Hoogle, but with less focus on type search
 
* [http://www.krugle.com/ Krugle] - Search code, no Haskell :(
 
* [http://www.krugle.com/ Krugle] - Search code, no Haskell :(
   
 
== Acknowledgements ==
 
== Acknowledgements ==
   
The code is all &copy; [http://www.cs.york.ac.uk/~ndm/ Neil Mitchell] 2004-2006. The initial version was done in my own time, and further refinement and reimplementation was done as part of my PhD. Various people gave lots of useful ideas, including my supervisor [http://www.cs.york.ac.uk/~colin/ Colin Runciman], and various members of the [http://www.cs.york.ac.uk/plasma/ Plasma group]. In addition the following people have also contributed some code:
+
The code is all &copy; [http://community.haskell.org/~ndm/ Neil Mitchell] 2004-2010. 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 [http://code.google.com/soc/ Google Summer of Code] with the [http://haskell.org/ haskell.org] mentoring organisation. Since then I have been working on Hoogle in my spare time. Various people have given lots of useful ideas, including my supervisor [http://www.cs.york.ac.uk/~colin/ Colin Runciman], and various members of the [http://www.cs.york.ac.uk/plasma/ Plasma group]. In addition the following people have also contributed some code or significant debugging work:
   
 
* [http://www.cs.kent.ac.uk/people/rpg/tatd2/ Thomas "Bob" Davie]
 
* [http://www.cs.kent.ac.uk/people/rpg/tatd2/ Thomas "Bob" Davie]
Line 197: Line 307:
 
* Esa Ilari Vuokko
 
* Esa Ilari Vuokko
 
* Udo Stenzel
 
* Udo Stenzel
  +
* [http://members.chello.nl/hjgtuyl/ Henk-Jan van Tuyl]
  +
* Gwern Branwen
  +
* Tillmann Rendel
  +
* David Waern
  +
* Ganesh Sittampalam
  +
* Duncan Coutts
  +
* Peter Collingbourne
  +
* Andrea Vezzosi
  +
* Ian Lynagh
   
In previous versions, all the data was taken from [http://www.zvon.org/other/haskell/Outputglobal/ 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.
+
In previous versions, all the data was taken from [http://www.zvon.org/other/haskell/Outputglobal/ 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.
   
 
[[Category:Tools]]
 
[[Category:Tools]]

Latest revision as of 22:27, 12 June 2017

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.

Below is the old manual, which is gradually being phased out.


Hoogle Use

Hoogle can be used in several ways:

This section describes Hoogle searches, and the flags available from the Hoogle command line tool. The information applies only to Hoogle 4 and is still being fleshed out.

Searches

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"

Modules: 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.

Packages: 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.

  • -V, --version Print out version information
  • -?, --help Show help on the command line flags
  • -v --verbose Verbose mode
  • --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

Database Creation

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.

You can create some default databases with (Windows users, please read Hoogle data on Windows first):

$ hoogle data

or you can create an extended database with

$ hoogle data all

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 file2.hoo. The result would be written as default.hoo. As before, --output=out.hoo can be specified.

The following script (from Matt Brown) may be helpful:

 $cat hoogleCombiner.sh 
 #!/bin/bash
 
 function combines {
   for f in ~/.hoogle/*.hoo
   do
     echo -n " $(readlink -f $f)"
   done
 }
 
 hoogle --output=$(readlink -f ~/.hoogle.hoo) combine $(combines)

Simon Michaels suggests:

 #!/bin/bash
 #
 # Search for hoogle databases in or under the directories/files specified
 # as arguments or hard-coded below (see allHoogleDbs), and combine them as
 # ~/.hoogle/default.hoo.  Lets you search all your code (and installed
 # haskell libs) at once.
 #
 # Usage:
 # $ hoogle-update-db
 # $ alias hoogle="hoogle --i=$HOME/.hoogle"
 # $ hoogle something
 
 # nb current hoogle cli quirks: path options should have two hyphens, one
 # equals, and no tildes, eg: --d=NOTILDEFILEPATH
 
 #set -x
 
 ARGS=$*
 function allHoogleDbs {
     for p in $ARGS ~/src/ ~/.cabal/share/ # add paths here
     do
         echo -n " $(findHoogleDbs $p)"
     done
 }
 
 function findHoogleDbs {
     find $1 -name '*.hoo'
 }
 function combineOpts {
   for f in $*
   do
     echo -n " $(readlink -f $f)"
   done
 }
 dbs=$(allHoogleDbs)
 echo Found $dbs
 mkdir -p ~/.hoogle
 hoogle --output=$(readlink -f ~/.hoogle/default.hoo) combine $(combineOpts $dbs)
 echo Created ~/.hoogle/default.hoo

Installing databases from Hackage

Packages on Hackage usually have .txt databases generated for you, so you can download those. You can find them in the html directories under the name [package-name].txt. So, for example, for diagrams-core the database can be found here: http://hackage.haskell.org/packages/archive/diagrams-core/0.6.0.2/doc/html/diagrams-core.txt

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.

Developer Flags

   ,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.

Firefox Integration

From the search bar: Go to the Hoogle website in Firefox and click on "Search plugin", top right hand corner (some versions of firefox instead will have an "add Hoogle" option in the list of search engines when you are viewing the Hoogle page). 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.

  1. Visit Hoogle's web interface: http://haskell.org/hoogle
  2. Right-click on the text input box and click "Add a Keyword for this Search..."
  3. Give it a nice short keyword like "h".

If you want to also search for special symbols in Firefox keyword search, modify the keyword search URL to be: javascript:window.location.href="http://haskell.org/hoogle?q=" + encodeURIComponent("%s")

Chrome Integration

Add to list of available search engines: Exactly as for the search bar in Firefox above.

As a keyword search: Under Chrome Preferences (Basic), select Manage Search Engines. You can then edit the keyword box appropriately.

To get the new Hoogle engine into the "default" section from the "other" section, make it default, and then re-select what was the original default.

(Works with Chrome on Mac OS X, at least).

GHCi Integration

Ever feel like having access to hoogle whilst messing around in GHCi? It's relatively easy to integrate the two.

The following will install hoogle as a shell command, and configure GHCi to have commands ":hoogle" showing all matches, and ":doc" showing haddock documentation for the first match:

  1. cabal install hoogle
  2. echo >> ~/.ghci ':def hoogle \x -> return $ ":!hoogle \"" ++ x ++ "\""'
  3. echo >> ~/.ghci ':def doc \x -> return $ ":!hoogle --info \"" ++ 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]

Done!

On Windows you should add the same lines

:def hoogle \x -> return $ ":!hoogle \"" ++ x ++ "\""
:def doc \x -> return $ ":!hoogle --info \"" ++ x ++ "\""

to file (XP/2003):

C:\Documents and Settings\[your windows account]\Application Data\ghc\ghci.conf 

or(Windows Vista/7):

C:\users\[your windows account]\Application Data\ghc\ghci.conf 


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, i.e. :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 :hoogle (just :h clashes with :help).

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

Emacs Integration

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.

Developers

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.

Theoretical Foundations

A lot of related work was done by Rittri [1] and Runciman [2] in the late 80's. Since then Di Cosmo [3] 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.

  1. 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)
  2. 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)
  3. 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:

Similar Tools

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 :(

Acknowledgements

The code is all © Neil Mitchell 2004-2010. 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. Since then I have been working on Hoogle in my spare time. 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:

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.