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

zou*_*oul 1 haskell nix

我已经通过Nix安装了GHC:

$ nix-env -i ghc
Run Code Online (Sandbox Code Playgroud)

然后我安装了aeson软件包:

$ nix-env -f "<nixpkgs>" -iA haskellPackages.aeson
Run Code Online (Sandbox Code Playgroud)

并将GHC指向Nix包文件夹:

$ export GHC_PACKAGE_PATH=~/.nix-profile/lib/ghc-8.0.1/package.conf.d/
Run Code Online (Sandbox Code Playgroud)

哪个似乎有效:

$ 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
    …
Run Code Online (Sandbox Code Playgroud)

但是aeson软件包从上面的软件包列表中丢失,因此无法加载。即使那里显然有东西:

$ ls /Users/zoul/.nix-profile/lib/ghc-8.0.1/ | grep ^ae
aeson-0.11.2.1
Run Code Online (Sandbox Code Playgroud)

我究竟做错了什么?

Pet*_*ons 5

您不能通过Nix方式安装Haskell库,因为ghc您使用的编译器不会在用户的配置文件中搜索库。因此,在那里安装库没有任何作用。Nixpkgs用户手册中对该主题进行了详细说明。我引用了“ 8.5.2.2。如何使用库安装编译器”中的相关内容:

GHC希望在其自己的lib目录中找到所有已安装的库。这种方法在传统的Unix系统上可以正常工作,但不适用于Nix,因为一旦构建,GHC的存储路径就不会改变。我们无法在该位置安装其他库。因此,我们的GHC副本不知道任何软件包,只有它们自己的核心库,例如基础库,容器,Cabal等。

但是,我们可以使用称为ghcWithPackages的特殊构建函数向GHC注册其他库。该函数需要一个参数:一个从Haskell软件包属性集映射到软件包列表的函数,该列表确定了该特定版本的GHC已知的库。例如,Nix表达式ghcWithPackages(pkgs:[pkgs.mtl])生成GHC的副本,该副本除了其常规核心软件包外还注册了mtl库:

$ 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
Run Code Online (Sandbox Code Playgroud)

该功能允许用户通过覆盖来定义自己的开发环境。将以下代码段添加到〜/ .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
                     ]);
  };
}
Run Code Online (Sandbox Code Playgroud)

可以使用nix-env -f“ <nixpkgs>” -iA myHaskellEnv安装该编译器。