Haskell 通过 Nix 安装时未在 ghc-pkg 中列出的软件包

Haskell packages not listed in ghc-pkg when installed through Nix

我已经通过 Nix 安装了 GHC:

$ nix-env -i ghc

那么我已经安装了aeson包:

$ nix-env -f "<nixpkgs>" -iA haskellPackages.aeson

并将 GHC 指向 Nix 包文件夹:

$ export GHC_PACKAGE_PATH=~/.nix-profile/lib/ghc-8.0.1/package.conf.d/

这似乎有效:

$ ghc-pkg list
/Users/zoul/.nix-profile/lib/ghc-8.0.1/package.conf.d
    Cabal-1.24.0.0
    array-0.5.1.1
    …

但是上面的包列表中缺少aeson包,无法加载。尽管那里显然有一些东西:

$ ls /Users/zoul/.nix-profile/lib/ghc-8.0.1/ | grep ^ae
aeson-0.11.2.1

我做错了什么?

您不能以这种方式在 Nix 中安装 Haskell 库,因为您使用的 ghc 编译器不会在您的用户配置文件中搜索库。因此,在那里安装库没有任何效果。 Nixpkgs user manual 中对此主题进行了非常详细的解释。我引用了“8.5.2.2。如何使用库安装编译器”中的相关内容:

GHC expects to find all installed libraries inside of its own lib directory. This approach works fine on traditional Unix systems, but it doesn’t work for Nix, because GHC’s store path is immutable once it’s built. We cannot install additional libraries into that location. As a consequence, our copies of GHC don’t know any packages except their own core libraries, like base, containers, Cabal, etc.

We can register additional libraries to GHC, however, using a special build function called ghcWithPackages. That function expects one argument: a function that maps from an attribute set of Haskell packages to a list of packages, which determines the libraries known to that particular version of GHC. For example, the Nix expression ghcWithPackages (pkgs: [pkgs.mtl]) generates a copy of GHC that has the mtl library registered in addition to its normal core packages:

$ nix-shell -p "haskellPackages.ghcWithPackages (pkgs: [pkgs.mtl])"

 [nix-shell:~]$ ghc-pkg list mtl
 /nix/store/zy79...-ghc-7.10.2/lib/ghc-7.10.2/package.conf.d:
     mtl-2.2.1

This function allows users to define their own development environment by means of an override. After adding the following snippet to ~/.nixpkgs/config.nix,

{
  packageOverrides = super: let self = super.pkgs; in
  {
    myHaskellEnv = self.haskell.packages.ghc7102.ghcWithPackages
                     (haskellPackages: with haskellPackages; [
                       # libraries
                       arrows async cgi criterion
                       # tools
                       cabal-install haskintex
                     ]);
  };
}

it’s possible to install that compiler with nix-env -f "<nixpkgs>" -iA myHaskellEnv.