Skip to content

Hoogle

Note: You may want to skip this section and return to it later when you understand basic Haskell syntax better.

Hoogle makes programming in Haskell a breeze once you understand the language basics. It is a search engine over the thousands of packages available on Hackage. Open a web browser and enter the URL hoogle.haskell.org (or click here). You should see a web page that looks something like this:

Hoogle start page

You can now enter the name of a function whose documentation you want to access, say the digitToInt function:

Hoogle digitToInt search

This tells you that digitToInt has the type Char -> Int. Even if you don't know the syntax for Haskell types yet, it is not hard to guess that this means that this function converts a Character to an Integer. You can click on the function to be taken to its detailed documentation:

Hoogle digitToInt documentation

The green text below the function signature on the previous page listing the search results tells us useful additional information. It says that this function is defined in the Data.Char module, so you need to import this module if you want to use the digitToInt function:

GHCi
>>> import Data.Char
>>> digitToInt '9'
9

The Data.Char module is part of the base package, which is essentially Haskell's standard library and is preinstalled. Other modules may be part of third-party packages. If you want to use those modules, you have to change the Haskell Stack configuration of your program so that these third-party packages are installed. We'll talk about management of packages in the Haskell Stack later. A function isn't necessarily defined in only one module or package. For example, the next package and module on the same line says that the RIO.Char.Partial module in the rio package also defines a digitToInt function.

So that's all basic information about functions that you would expect any basic API documentation to provide, and it's nice but not earth-shattering that we have a search engine like Hoogle to search for functions with various names across all packages available on Hackage. What's really cool is that we can search for functions on Hoogle even if we don't know their names.

Let's say we are looking for a function that takes a list of elements of type a. Haskell's syntax for such a list is [a]. We want to partition this list into two sublists, the first containing the elements that satisfy some condition, the second containing the elements that do not satisfy the condition. The return type should therefore be a pair of lists, again containing elements of type a. Haskell's syntax for this is ([a], [a]). We test whether a given element of type a satisfies the condition we are interested in using a function that returns True if the element satisfies the condition, and False otherwise. The type of such a function is a -> Bool—it maps an element of type a to a Boolean value. Now if we want to have a function that allows us to partition a list of as into two lists based on some condition, we need to provide the condition, a function of type a -> Bool, and the input list, of type [a] as arguments to the function, and the return value should be a pair of lists of type ([a], [a]). The Haskell type signature of such a function is (a -> Bool) -> [a] -> ([a], [a]). The arrows separate function argument types and the return type from each other. So this function takes a function of type a -> Bool as its first argument, a list of type [a] as its second argument, and it returns a pair of lists.

We can simply type this type signature into Hoogle, and it will give us a list of functions with this type signature that it finds.1

Hoogle partition search

In this case, the third function in the result list, unsurprisingly called partition, is the one we are looking for. You can verify this by clicking on its documentation. Again, the green text after the function signature tells us that we need to import the module Data.List if we want to use this function, and that we do not need to install any additional packages because this module is part of the base package.

GHCi
>>> import Data.List
>>> partition even [1,2,3,4,5,6]
([2,4,6],[1,3,5])

Do you need to guess the argument order of the function you're looking for correctly? Maybe the implementor of the function thought that it would be better to provide the list to be partitioned as the first argument and the condition used to partition this list as the second argument. The resulting type signature would be [a] -> (a -> Bool) -> ([a], [a]). As it turns out, Hoogle is smart enough to find all functions whose arguments match the given types, in any order. Try it out. Search for this permuted function signature and see that you'll once again get partition as one of the hits.

I will not talk about Hoogle in the remainder of this book anymore. However, remember that you have this extremely useful tool at your disposal whenever you need to figure out whether there already exists a function that does exactly what you want to do.


  1. You may wonder whether it is important that we used a as the type variable here. It is not. You can try searching for a function of type (b -> Bool) -> [b] -> ([b], [b]) or (t -> Bool) -> [t] -> ([t], [t]), and you will get the same search results. After all, a is a type variable and is therefore completely equivalent to the variable b or t