I talked about this a little bit here:
Basically, there are a set of Haskell tools that must be built with with the same version of GHC you’re using. A few that come to mind are HLS, weeder, and fourmolu/ormolu (maybe?).
If you override the top-level Haskell package set (like haskell.packages.ghc925
in the above example), you have a chance of accidentally changing dependencies of these developer tools, which can cause them to no longer compile.
Here’s a simple example. Imagine you have a local package that needs to be built with ghc-9.2.5, but uses aeson-1.5.6.0:
final: prev: {
haskell = prev.haskell // {
packages = prev.haskell.packages // {
ghc925 = prev.haskell.packages.ghc925.override {
overrides = haskFinal: haskPrev: rec {
my-cool-pkg = haskFinal.callCabal2nix "my-cool-pkg" ./. { };
aeson = haskFinal.callHackage "aeson" "1.5.6.0" { };
};
};
};
};
}
With this overlay, while you’ll be able to build haskell.packages.ghc925.my-cool-pkg
, you likely wouldn’t be able to build haskell.packages.ghc925.haskell-language-server
, since haskell-language-server
requires aeson-2.0. Although, most users will want to use haskell.packages.ghc925.haskell-language-server
in their development environment.
(This is just an example. In practice, aeson-1.5 might not compile with ghc-9.2.5, or haskell-language-server might be able to compile with older versions of aeson.)
Alternatively, if you create a separate package set, you can override whatever you want.
For example:
final: prev: {
my-haskell-pkg-set = prev.haskell.packages.ghc925.override {
overrides = haskFinal: haskPrev: rec {
my-cool-pkg = haskFinal.callCabal2nix "my-cool-pkg" ./. { };
aeson = haskFinal.callHackage "aeson" "1.5.6.0" { };
};
};
}
With just this overlay, you’ll be able to build my-haskell-pkg-set.my-cool-pkg
, as well as haskell.packages.ghc925.haskell-language-server
.
The takeaway here is that when working with Nixpkgs, it is very easy to create your own packages and package sets. It often helps to do so, so that you don’t accidentally override something that is used in another place.