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.cabalfile under thebuild-dependssection. -
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
callCabal2nixand assign it to theemaname in the Haskell package set by adding it to thepackagesargument of yourflake.nixthat is using haskell-flake:{ perSystem = { self', config, pkgs, ... }: { haskellProjects.default = { packages = { ema.source = inputs.ema; }; }; }; } -
Re-run the nix shell (
nix develop).
Using a multi-package Haskell Git repo
If you want to override multiple dependencies whose source exist in the same mono repo (for e.g., foo and bar in haskell-multi-nix, you can do so as follows:
-
Add a flake input pointing to the monorepo (eg.,
haskell-multi-nixGit repo) inflake.nix:{ inputs = { haskell-multi-nix.url = "github:srid/haskell-multi-nix"; haskell-multi-nix.flake = false; }; } -
Add a separate entry in
haskellProjects.<name>.packagesfor each of the package in the subdirectories:{ perSystem = { self', config, pkgs, ... }: { haskellProjects.default = { packages = { foo.source = inputs.haskell-multi-nix + /foo; bar.source = inputs.haskell-multi-nix + /bar; }; }; }; }
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.