Overriding dependencies

Haskell libraries ultimately come from Hackage, and nixpkgs contains most of these. Adding a library to your project involves modifying the .cabal file and restarting the nix shell. The process is typically as follows:

  • Identify the package name from Hackage. Let’s say you want to use ema
  • Add the package, ema, to the .cabal file under the build-depends section.
  • Exit and restart the nix shell (nix develop).

Step (3) above will try to fetch the package from the Haskell package set in nixpkgs (pkgs.haskellPackages by default). For various reasons, this package may be either missing or marked as “broken”. In such cases, you will have to override the package locally in the project (see the next section).

Overriding a Haskell package source

In Nix, it is possible to use an exact package built from an arbitrary source - which can be a Git repo, local directory or a Hackage version.

Using a Git repo

If you want to use the master branch of the ema library, for instance, you can do it as follows:

  • Add a flake input pointing to the ema Git repo in flake.nix:
    {
      inputs = {
        ema.url = "github:srid/ema";
        ema.flake = false;
      };
    }
  • Build it using callCabal2nix and assign it to the ema name in the Haskell package set by adding it to the packages argument of your flake.nix that is using haskell-flake:
    {
      perSystem = { self', config, pkgs, ... }: {
        haskellProjects.default = {
          packages = {
            ema.source = inputs.ema;
          };
        };
      };
    }
  • Re-run the nix shell (nix develop).

Using a Hackage version

packages.<name>.source also supports Hackage versions. So the following works to pull ema 0.8.2.0:

{
  perSystem = { self', config, pkgs, ... }: {
    haskellProjects.default = {
      packages = {
        ema.source = "0.8.2.0";
      };
    };
  };
}

Using a nixpkgs version

haskellProjects.default = {
  settings = {
    fourmolu = { super, ...}: { custom = _: super.fourmolu_0_13_1_0; };
  };
};

Overriding a Haskell package settings

See Package Settings

Sharing dependency overrides

Project modules export both packages and settings options for reuse in downstream Haskell projects.

Links to this page
  • Project modules

    The idea here being that you can “connect” two Haskell projects such that they depend on one another while reusing the overrides – packages (see Overriding dependencies) and settings (see Package Settings) – from one place. For example, if you have a project “foo” that depends on “bar” and if “foo”’s flake.nix has “bar” as its input, then in “foo”’s haskellProject.default entry you can import “bar” as follows:

  • Guide
  • Creating package sets

    A “project” in haskell-flake primarily serves the purpose of developing Haskell projects. Additionally, a project also exposes the final package set via the readonly option outputs.finalPackages. This package set includes the base packages (basePackages), the local packages as well as any dependency overrides you set. Since we are are only interested in creating a new package set, we can use empty local packages and disable the dev shell: