coldwa.st
All guidesProgrammingWebDataToolsDatabasesHaskellConceptsCabal & buildsToolchainCompilerPerformanceEditor & HLS

Haskell · tooling · search

Hoogle: searching Haskell by type signature

By ColdwastUpdated Aug 10, 20267 min read#haskell#hoogle#tooling
A wall of pale wooden card-catalogue drawers with small metal label holders, one drawer pulled out at mid height revealing tightly packed upright index cards
A wall of wooden catalogue drawers, one pulled open on its tightly packed index cards. Card catalogues let you look things up by title or by author - two indexes over the same collection. Hoogle adds a third: the shape of what you want.

Most language documentation lets you search by name. That works when you know what the function is called. It does not help with the far more common situation: you know the shape of the thing you need - you have a list of Maybe values and you want a list of the ones that are present - but you have no idea what its author named it.

Hoogle is the Haskell API search engine, and its distinguishing feature is that it searches by type signature as well as by name. That is only practical because Haskell types are precise enough to identify a function almost uniquely.

Searching by name

The ordinary case works as you would expect. Type foldr and you get the function, its type, the module it lives in, and its documentation. Partial names work too, and Hoogle tolerates approximate spelling, so conc will find concat and concatMap.

Searching by type

The interesting case is querying with a type instead. Suppose you have a [Maybe a] and want an [a]. You do not need to remember the name:

[Maybe a] -> [a]

That query finds catMaybes, in Data.Maybe. The same trick answers a whole class of questions:

(a -> b) -> [a] -> [b]        -- finds map
[[a]] -> [a]                  -- finds concat
(a -> Bool) -> [a] -> [a]     -- finds filter, takeWhile, dropWhile
Monad m => [m a] -> m [a]     -- finds sequence

Type variables are matched structurally, not literally: writing a or x makes no difference, because Hoogle unifies them. It will also return results whose types are more general than your query, which is usually what you want - a function on any Foldable will answer a question you asked about lists.

Side view at desk level of one hand typing on a silver laptop keyboard, the machine's USB and headphone ports visible along the edge, with a wall of bookshelves blurred behind
A hand on a laptop keyboard photographed from the side, close enough to show the USB and headphone ports along the case edge; shelves recede out of focus behind. Type search is a typing exercise: you describe the shape you want and let the index do the recall.

Query syntax worth knowing

  • Restrict to a package - +containers limits results to that package; -containers excludes it.
  • Restrict to a module - +Data.Map works the same way for module names.
  • Mix name and type - map +base narrows a common name to the standard library.
  • Search operators - you can paste an operator such as <$> directly.
  • Find a type or class - searching a capitalised name such as Traversable returns the definition rather than functions using it.

What Hoogle indexes, and what it does not

The public instance indexes a large set of Hackage packages, but not all of Hackage, and the default search scope is narrower than the full index. This matters in practice: a query that returns nothing has not proved the function does not exist. It may simply live in a package outside the scope you searched. Widening the scope, or adding an explicit +package, often turns an empty result into the answer.

Hoogle also matches on types as written, so a function hidden behind a type synonym or a newtype wrapper may not surface for the underlying shape. If a query looks like it should match and does not, try the more general form - drop a constraint, or replace a concrete type with a variable.

Running Hoogle over your own dependencies

The public site indexes public packages. It does not know about your project, your private modules, or the exact versions you have pinned. A local instance does, and it is the version that pays off on a real codebase:

-- with Cabal
cabal install hoogle
hoogle generate
hoogle server --local --port=8080

-- with Stack
stack hoogle -- generate --local
stack hoogle -- server --local --port=8080

Generating the database builds an index from the packages actually installed for your project, so searches return the functions you can really call - at the versions you are really using. Which of the two workflows you use depends on the build tool you picked; see Stack vs Cabal if you have not chosen yet. Both are installed for you by GHCup.

Hoogle inside the editor

You do not have to leave your editor to get most of this. Haskell Language Server surfaces types and documentation on hover and at completion, which covers the "what is this thing" half. Hoogle covers the other half - the "what is the thing I do not know the name of" half - and that is the one a language server cannot answer, because you have nothing to point at yet.

Why type search works in Haskell

It is worth being clear about why this is not a feature every language could copy. Haskell functions are typically pure and their signatures carry most of the meaning: (a -> b) -> [a] -> [b] has very few sensible implementations, so the type alone nearly identifies the function. In a language where a signature is (Object, Object) -> Object, or where any function may do anything at all, the same query would return everything and therefore nothing. The precision of the type system is what makes the index useful.

FAQ

What is Hoogle? A search engine for Haskell libraries. It looks up functions, types and classes by name, and also by type signature.

How do I search Hoogle by type? Enter the signature itself, for example [Maybe a] -> [a]. Type variable names do not matter; results whose types are more general than the query are included.

Why does my search return nothing? Most often the package is outside the scope you searched, not missing. Add +packagename, widen the scope, or generalise the query by dropping a constraint.

Can Hoogle search my own project? Yes, by generating a local database with hoogle generate (or stack hoogle -- generate --local) and running hoogle server --local. That indexes the packages and versions your project actually uses.

Is Hoogle the same as Hayoo? No. Hayoo is a separate Haskell search engine with its own index and scope. Hoogle is the one most commonly linked from Haskell documentation.

Recommended

Run a local Hoogle for your team

A local Hoogle server indexes your project's own dependencies, and a small always-on VPS makes it reachable by the whole team instead of one laptop. DigitalOcean offers VPS and cloud servers suited to that kind of small persistent service.

See DigitalOcean cloud →

Affiliate link - supports these free guides.

Independent, community-maintained guide. coldwa.st is a programming-resources site; this article is new, original explanatory writing about Haskell tooling, and is not affiliated with Hoogle, Hackage, Stackage or the GHC maintainers. Commands reflect standard Haskell tooling - verify options against the current Hoogle documentation, which changes between releases.

Related reading: Stack vs Cabal · How to Add a Dependency in Cabal