суббота, 23 мая 2015 г.

A dense summary of Peter Simons Haskell-on-Nix video

Listing & installing Hackage packages

  - listing compilers:
nix-env -qaP -A haskell.compiler
  - listing packages (essentially Hackage names + NixOS-curated version):
nix-env -qaP -A haskellPackages
nix-env -qaP -A haskell.packages.ghc7101
  - installing packages
nix-env -iA haskellPackages.foo
nix-env -iA haskell.packages.ghc7101.foo

Environmenting

  Enter a shell with *ghc* = =ghc-7.10.1=:
nix-shell -p haskell.compiler.ghc7101
  The following makes cabal just work:
nix-shell -p haskell.compiler.ghc7101 --command "cabal configure"
cabal build
  Build two environments with different versions of GHC, until GC strikes:
nix-env -p ~/ghc-7.6.3 -iA haskell.compiler.ghc763
nix-env -p ~/ghc-7.8.4 -iA haskell.compiler.ghc784
  Same, persistently, with regard to GC:
PROFILE_DIR=/nix/var/nix/profiles/per-user/$USER
nix-env -p $PROFILE_DIR/ghc-7.6.3 -iA ...

Persistent, name-bound user-profile-wide compiler+package environment

  Putting this in =~/.nixpkgs/config.nix=:
  {
    packageOverrides = super: let self = super.pkgs; in
    {
      myHaskellEnv =
        self.haskell.packages.ghc7101.ghcWithPackages
          (haskellPackages: with haskellPackages; [
            arrows async cabal-install case-insensitive
            cgi criterion hspec HStringTemplate
          ]);
    };
  }
  ..and then, this in =~/.bashrc=:
  if [ -e ~/.nix-profile/bin/ghc ]; then
          eval $(grep export ~/.nix-profile/bin/ghc)
  fi
  ..wraps GHC and allows for:
nix-env -iA myHaskellEnv

Per-project environments

Manual generation, no cabal integration

    =~/src/foo/shell.nix=:
    { compiler ? "ghc7101" }:
    with (import <nixpkgs> {}).pkgs;
    let
      ghc = haskell.packages.${compiler}.ghcWithPackages
              (pkgs: with pkgs; [ aeson lens monad-par ]);
    in
      stdenv.mkDerivation {
        name = "my-haskell-env-0";
        buildInputs = [ ghc ];
        shellHook = "eval $(grep export ${ghc}/bin/ghc)";
      }

cd ~/src/foo/
nix-shell --argstr compiler ghc784

Automated through cabal2nix, has cabal integration

cabal2nix --shell . >shell.nix
nix-shell --command "cabal configure"
cabal build
    ..where cabal2nix emits something like this:
    with (import <nixpkgs> {}).pkgs;
    let pkg = haskellPackages.callPackage
                ({ mkDerivation, base, stdenv, transformers }:
      mkDerivation {
            pname = "mtl";
            version = "2.2.1";
            src = ./.;
            buildDepends = [ base transformers ];
            homepage = "http://github.com/ekmett/mtl";
            license = stdenv.lib.licenses.bsd3;
      }) {};
    in
      pkg.env

Inject locally-derived packages into the global namespace

cd ~/src/foo
cabal2nix . > default.nix

    Then, in =~/.nixpkgs/config.nix=:
    {
      packageOverrides = super: let self = super.pkgs; in
      {
        foo = self.haskellPackages.callPackage ../src/foo {};
      };
    }
nix-env -iA foo
    Or, alternatively, to make it available to other packages:
    {
      packageOverrides = super: let self = super.pkgs; in
      {
        haskellPackages = super.haskellPackages.override {
          overrides = self: super: {
            foo = self.callPackage ../src/foo {};
            bar = self.callPackage ../src/bar {};
          };
        };
      };
    }