Automatic import chasing across the Internet for Haskell modules

Just Google and Import (Recursively)

Suppose you decide you want some XML functionality in your Haskell program. You google for e.g. "haskell XML". You find HaXML and a variety of other packages. You browse the HaXML docs and decide it has the module you need. You just add that module to your program and recompile. SearchPath takes care of downloading and unpacking the relevant package and putting it on your ghc search path. Your program just works.

Now suppose instead that you want to use a complex set of packages like HappS(tack). This package has a lot of dependencies. SearchPath takes care not only of downloading the relevant HAppS modules, it also notices what modules they import and takes care of downloading and unpacking their dependencies as well e.g. HaXML, HSpread, System.Log, etc.

Automatically Recompile and Re-Run on Code Changes

With the run flag, SearchPath will automatically start your program on a successful compile. When you change your code, SearchPath will detect the change, download any new modules/packages that are required, and attempt to recompile. If the recompile produces errors, they appear on console. If the recompile succeeds, the old code is shutdown and the new code started with the same arguments. No more manual compile-debug- restart cycle.

Package, Version Control, and Build-System Agnostic

Searchpath is compatible with source hiearchies stored in cabal packages, unpacked web hierarchies, darcs/git/svn repos, tar.gz files and more. Mapfiles can include instructions for each package that tell it how to retrieve, unpack, build, and find the modules that were imported. A nice consequence of this model is that pulling from version controlled source repos is preffered over pulling cabal tarballs. The upshot is that, when you find errors in an imported package, you can modify the source in place, and send in a patch.

Easily Modify and Submit Changes to Imported Packages and

Often one discovers bugs or missing features in imported packages. SearchPath makes it easy to make changes in these packages, test them in your code, and then submit them back to their authors for inclusion in the next version of their code.

Without SearchPath, the dominant alternative is to use the tarball, realize that it needs changes, go and find the source repo, manually modify your code path to point to this source repo instead of the "installed" package, then try to remember what you were doing to spur this activity.

Rather than downloading tarballs, SearchPath attemps to pull the actual darcs, git, svn, etc source repositories within which dependent modules reside. SearchPath then makes sure that compiler's module search path then includes the source in the local copy of these repos. Changes you make in these modules are then immediately visible in your program. Right now, you still have to go through the changes repos and manually submit changes to the package authors. A near term improvement to SearchPath will be a single command that finds changes in all imported packages and lets you do batch submission to the package authors.

Automatic Version/Dependency Tracking

Rather than force module users of packages to track which versions of a package are compatible with which versions of their code, SearchPath puts that responsibility on module authors. When a module or package of modules changes in a way that will break code, the new version appears in the module map with a new date-time stamp. If a package has a particular date and is dependent on other packages. SearchPath will only import chase through older versions of the package. Changes which are simply performance improvements or feature enhancements but that don't break code, don't get new map entries.

This approach is substantially better than manual dependency tracking. Dependent module users benefit from changes that are not intended to break them without any work. Having random version number conventions for different packages is confusing and pointless.

A Global Module Map With Local Control

SearchPath defaults to using a global map of module locations hosted on This map allows SearchPath to lookup a module prefix and follow the instructions necessary to download it and build it locally. Command line options allow users to use one or more alternate module maps in addition to or instead of the global one. The result is that you can easily mix global/public repos, with organzational, divisional, personal, and project repos with the more local ones taking precedence over the globals as needed.

Package/Version/Build System Agnostic

Searchpath will pull relevant code from tarballs, svn or darcs repos, etc. If the code requires a local build step, you can have searchpath run cabal or configure after the download. The map file is verify flexible in this regard.

Typical Usage Examples

$ sp --help
shows usage information
$ sp ghc --make -o myProgram -i src src/Main.hs
module chase in src directory and using the default module map to build myProgram
$ sp ghc --make -o myProgram -i src src/Main.hs --run arg1 arg2
same as above and run the program, recompiling and restarting on changes to source

How to install

Requirements: curl ghc
curl -o SearchPath.hs
ghc --make SearchPath.hs -o sp
sudo mv sp /usr/local/bin
License is BSD3.

Note: curl is required to run searchpath as well so you need to have it installed. Fortunately, there are binaries for lots of platforms likely including yours available.

How to add projects to the default map

Check out the current default map file. Pull the darcs repo, modify and send in a patch. See below.

How to Modify/Impove Searchpath code/docs/website

darcs get
Send patches to: searchpath<nospam>@
Some HTML layout help would be very appreciated.


Version 0.9.3 (07/24/2009)
  • Automated Version/Dependency Tracking (see text on left)
  • Only show used module paths in output compile command
Version 0.9.2 (1/10/2008)
  • default to using ~/.Searchpath as cache so you don't have to wait
  • fixed bug that won't run ghci if executable exists
  • autorecompile on source changes even after prior failure
  • write into current directory as and use if present to maximize stability (you can add this file to the repo).
  • fixed bug if executable exists and no run.
  • the cachedir now keeps all module hierchies in the same place
  • code now supports the invariant that change should only happen via modifications to module maps or source hierarhcies. No surprises.
Version 0.9.1 (12/28/2007)
  • --run argument to automatically recompile/restart on code changes
  • negative caching for faster load times
  • use command sequences to retrieve and build required packages if necessary
  • allow build command sequences for tgz files as well
Version 0.9 released (12/18/2007)
  • handling tagged darcs/svn repos
  • handling .tgz archives
  • massive code cleanup
  • substantially faster
  • easier/better command line options
  • better usage documentation
  • handling non-local haskell files