Home Explore Blog Models CI



nixpkgs

11th chunk of `doc/languages-frameworks/haskell.section.md`
598fa6cd0e583ab372d203ae8b548a930a8429a22bf27a200000000100000fc2
packages using the same environment in conjunction with
[cabal.project files][cabal-project-files].
Say our example above depends on `distribution-nixpkgs` and we have a project
file set up for both, we can add the following `shell.nix` expression:

```nix
{
  pkgs ? import <nixpkgs> { },
}:

pkgs.haskellPackages.shellFor {
  packages = hpkgs: [
    # reuse the nixpkgs for this package
    hpkgs.distribution-nixpkgs
    # call our generated Nix expression manually
    (hpkgs.callPackage ./my-project/my-project.nix { })
  ];

  # development tools we use
  nativeBuildInputs = [
    pkgs.cabal-install
    pkgs.haskellPackages.doctest
    pkgs.cabal2nix
  ];

  # Extra arguments are added to mkDerivation's arguments as-is.
  # Since it adds all passed arguments to the shell environment,
  # we can use this to set the environment variable the `Paths_`
  # module of distribution-nixpkgs uses to search for bundled
  # files.
  # See also: https://cabal.readthedocs.io/en/latest/cabal-package.html#accessing-data-files-from-package-code
  distribution_nixpkgs_datadir = toString ./distribution-nixpkgs;
}
```

<!-- TODO(@sternenseemann): deps are not included if not selected -->

### haskell-language-server {#haskell-language-server}

To use HLS in short: Install `pkgs.haskell-language-server`, e.g. in
`nativeBuildInputs` in `shellFor` and use the `haskell-language-server-wrapper`
command to run it. See the [HLS user guide] on how to configure your text
editor to use HLS and how to test your setup.

HLS needs to be compiled with the GHC version of the project you use it
on.

``pkgs.haskell-language-server`` provides
``haskell-language-server-wrapper``, ``haskell-language-server``
and ``haskell-language-server-x.x.x``
binaries, where ``x.x.x`` is the GHC version for which it is compiled. By
default, it only includes binaries for the current GHC version, to reduce
closure size. The closure size is large, because HLS needs to be dynamically
linked to work reliably. You can override the list of supported GHC versions
with e.g.

```nix
pkgs.haskell-language-server.override {
  supportedGhcVersions = [
    "90"
    "94"
  ];
}
```
Where all strings `version` are allowed such that
`haskell.packages.ghc${version}` is an existing package set.

When you run `haskell-language-server-wrapper` it will detect the GHC
version used by the project you are working on (by asking e.g. cabal or
stack) and pick the appropriate versioned binary from your path.

Be careful when installing HLS globally and using a pinned nixpkgs for a
Haskell project in a `nix-shell`. If the nixpkgs versions deviate to much
(e.g., use different `glibc` versions) the `haskell-language-server-?.?.?`
executable will try to detect these situations and refuse to start. It is
recommended to obtain HLS via `nix-shell` from the nixpkgs version pinned in
there instead.

The top level `pkgs.haskell-language-server` attribute is just a convenience
wrapper to make it possible to install HLS for multiple GHC versions at the
same time. If you know, that you only use one GHC version, e.g., in a project
specific `nix-shell` you can use
`pkgs.haskellPackages.haskell-language-server` or
`pkgs.haskell.packages.*.haskell-language-server` from the package set you use.

If you use `nix-shell` for your development environments remember to start your
editor in that environment. You may want to use something like `direnv` and/or an
editor plugin to achieve this.

## Overriding Haskell packages {#haskell-overriding-haskell-packages}

### Overriding a single package {#haskell-overriding-a-single-package}

<!-- TODO(@sternenseemann): we should document /somewhere/ that base == null etc. -->

Like many language specific subsystems in nixpkgs, the Haskell infrastructure
also has its own quirks when it comes to overriding. Overriding of the *inputs*
to a package at least follows the standard procedure. For example, imagine you
need to build `nix-tree` with a more recent version of `brick` than the default
one provided by `haskellPackages`:

Title: Nix Haskell Environments: `shellFor` and Haskell Language Server
Summary
This chunk continues the `shellFor` example, demonstrating how to configure a Haskell development environment to include both Nixpkgs-provided and local packages, and how to set environment variables. It then introduces the Haskell Language Server (HLS) and explains its integration with Nix, detailing how to install `pkgs.haskell-language-server` in `nativeBuildInputs` and use `haskell-language-server-wrapper`. The text emphasizes that HLS must match the project's GHC version and shows how to override `pkgs.haskell-language-server` to support multiple GHC versions. It also warns against issues with globally installed HLS when using pinned Nixpkgs for projects, recommending HLS be sourced from the project's `nix-shell`. Finally, it advises using tools like `direnv` or editor plugins for seamless `nix-shell` integration and transitions to the topic of overriding Haskell packages.