haskellmodulepackage

How do I find the Haskell package containing a particular module


Another elementary question about using GHC: finding the package containing a module when using existing code. This question has been asked several times here, but none of the answers seem to really address this basic issue.

I expected that the answer would be to use hackage, but the search facility is peculiar or perhaps under-documented.

Example: I have

import System.Random

So I visit hackage and try to search for System.Random with the search packages facility. I get back mersenne-random-pure64, randfile and normaldistribution. But not the random package which is what I am expecting from past experience.

Searching with just Random, however, does return the random package among many others. Which may suggest that "." is some sort of meta-character. But what, and why is there no documentation?

Somewhere, I saw that the search was in a package's metadata without defining the term metadata. I downloaded the random package tarball and looked at the contents and "System.Random" was in the description field of random.cabal among other places, so why can't Hackage see it?

Or is there some other way to identify a package or packages containing a particular module?


Solution

  • Here's an awful hack you can use:

    cabal list | grep '^\*' | cut -d' ' -f2 | xargs cabal info 2>/dev/null \
      | grep '^\(\*\| *System\.Random$\)' | grep -B1 ' *System\.Random$' \
      | grep '^\*'
    

    Explanation:

    Of course, if cabal could do the same thing itself, that would be much cleaner and probably much faster as well.

    On my system, the pipeline above prints only the random package, which seems right to me. A more exciting search for Data.List shows that this can produce many results if there are such, listing base, base-noprelude, bizzlelude, bizzlelude-js, fay-base, haskell2010, haskell2020, liquid-base, rerebase, and safe-coupling. More packages than I expected export that module!

    Compared to using hoogle, this uses a more complete initial package list (all of Hackage rather than all of Stackage) and gives you flexibility over whether you are searching for an exact module name (as above) or the prefix of a module hierarchy (drop the $ from the module patterns). However it is more fragile, possibly producing false positives if your module pattern matches some other part of the package information than the exported modules list, and is tightly coupled with details of cabal's current output format.