Installing Dhall using Nix

I apologize in advance if this question is better directed to Nix forums than here. I thought since the Dhall maintainers also maintain the Dhall Nix packages I might get a better answer here.

Anyway, I am new to Nix, having recently switched from using brew. I noticed that the latest (1.41.1) Dhall binaries, which have been out for two months, haven’t been updated on nixos-unstable yet. Does one need to open an issue on the nixpkgs github repo to have the latest Dhall binaries pulled in? From whatever little Nix knowledge that I have, it looks to me that updating Dhall on Nix is automated. But then again I don’t know how long it normally takes for a new version to show up on nixpkgs.

What’s the best way to get the latest Dhall binaries using Nix package management?

Thanks

Disclaimer: I am godawful with nix, so take that with a grain of salt…

dhall-haskell has some info here on how to grab the latest binaries with nix: GitHub - dhall-lang/dhall-haskell: Maintainable configuration files

And this is probably a really wrong way of doing it, but as I said, I’m terrible at nix, so here’s the derivation I use to grab the actual latest (i.e. unreleased) binaries off hydra (can be repeated for each individual tool). (I use home-manager, so it’s home.packages rather than environment.systemPackages, but can use whatever.)

{pkgs, ...}: {
  home.packages = with pkgs; [
    # Grab latest Dhall tooling from Hydra
    (/.
      + builtins.toPath
      (builtins.fromJSON (builtins.readFile (builtins.toPath
        (builtins.fetchurl
          "https://hydra.dhall-lang.org/job/dhall-haskell/master/linux-dhall/latest/api/get-info"))))
      .outPath)
  ];
}

This requires having the Dhall binary cache enabled, e.g. having

    binaryCaches = [
      "https://cache.dhall-lang.org"
    ];
    binaryCachePublicKeys = [
      "cache.dhall-lang.org:I9/H18WHd60olG5GsIjolp7CtepSgJmM2CsO813VTmM="
    ];

Someone who knows more about Nix can probably be more useful though!

Thank you! I will try this out.

The simplest thing to do is just wait. The Haskell maintainers for Nixpkgs periodically update the Haskell package set to build the latest versions of package

However, if you can’t wait, the next thing you can do is to clone the dhall-haskell repository and run:

$ nix-env --install --attr dhall --file ./default.nix

That also works for installing other Dhall packages, too, like dhall-json, dhall-lsp-server, etc.

Thank you for the suggestion. I have been using a docker image for now, but I’ll keep this in mind the next time I need to use the latest release.

Just a short while ago I came across this Github issue. I am not familiar with Haskell (or its toolchains), but assuming Nix is still using stackage as you alluded to in your reply, their recent nightly version seems to have picked up the latest dhall version. Hopefully, it will get merged into nixpkgs soon.

Thanks again.

In case it’s helpful, here’s a flake.nix file I used to get dhall 1.41.1 (I needed the showConstructor keyword). This has just those dhall packages/utilities that I needed.

Note the package overrides were needed as of nixpkgs rev 30d3d79b7d3607d56546dd2a6b49e156ba0ec634.

flake.nix
{
  description = "Flake for dhall and related utilites";

  inputs = {
    utils.url = "github:numtide/flake-utils";
  };

  outputs = { self, nixpkgs, utils }:

    utils.lib.eachDefaultSystem (system:
      let

        pkgs = nixpkgs.legacyPackages."${system}";

        noCheck = p: pkgs.haskell.lib.dontCheck p;
        noHaddock = p: pkgs.haskell.lib.dontHaddock p;
        fastHaskell = p: noCheck (noHaddock p);

        # Haskell Package currently includes v1.39.0 of dhall;
        # however, the fact-models package needs (at least) 1.41
        # because it uses the `showConstructor` keyword.
        #
        # Here, we override the versions of dhall and other apps
        # newer versions of each.
        # I got this idea from:
        # https://discourse.dhall-lang.org/t/install-dhall-1-32-0-on-nixos/279/4
        haskellPackagesNewDhall = pkgs.haskellPackages.override {
          overrides = self: super: {

            dhall = fastHaskell (self.callHackageDirect
              {
                pkg = "dhall";
                ver = "1.41.1";
                # To get this sha256 I run `nix build .`
                # and then took the "got:" hash from the result
                # and then ran  `nix hash to-base32 <output of got:>`
                sha256 = "18icyr13lr2aqqam7arfvpri6zaxa1wvlfyyyza6sabz3g96jsik";
              }
              { });

            dhall-docs = fastHaskell (self.callHackageDirect
              {
                pkg = "dhall-docs";
                ver = "1.0.9";
                sha256 = "05chpsd2sx6xzhv5nizbvxxdawidkywx3pj3pwc8a2p10iaqz2gv";
              }
              { });

            dhall-toml = fastHaskell (self.callHackageDirect
              {
                pkg = "dhall-toml";
                ver = "1.0.2";
                sha256 = "1x7hkjr202a92j5qn0z4yg281mjzkaf59773pj32h8ic2vivaj0h";
              }
              { });

            dhall-json = fastHaskell (self.callHackageDirect
              {
                pkg = "dhall-json";
                ver = "1.7.10";
                sha256 = "0bqc5vgzq9ns05ipbhyw3317zill76gk7zp6v9l3x8prhamhhp1z";

              }
              { });

            dhall-hpack-cabal = fastHaskell (self.callHackageDirect
              {
                pkg = "hpack-dhall";
                ver = "0.5.5";
                sha256 = "0q77kcysz70dxffs41fmpmkhlrix4rr1fi1apf1fdmxgz30d1m3f";

              }
              { });


            /*
            The following are updated Haskell packages that the applications
            above require or updates that the packages require
            (e.g. mmark requires newer versions for lucid and modern-uri
            than are available from nixpkgs)
            */
            hpack = fastHaskell (self.callHackageDirect
              {
                pkg = "hpack";
                ver = "0.34.7";
                sha256 = "1yb7243jr4ibyngrs4ldcs6iwsibdvzc0bgwls1fh9aj7bvsks2r";

              }
              { });

            lucid = fastHaskell (self.callHackageDirect
              {
                pkg = "lucid";
                ver = "2.11.0";
                sha256 = "1r78fp79qrmrrdgcnwvh9iqpvj973vh9vff63gi42mdp91mgzzmi";

              }
              { });

            modern-uri = fastHaskell (self.callHackageDirect
              {
                pkg = "modern-uri";
                ver = "0.3.4.4";
                sha256 = "19qwfrida77mxix4v41qyvanfxy8qljg4fxz9ccxlcjdbks5v6pa";

              }
              { });

            mmark = fastHaskell (self.callHackageDirect
              {
                pkg = "mmark";
                ver = "0.0.7.6";
                sha256 = "14dzl3a2ypbydxlw3pl1bj8p1krazxy56gs0v326q2jvdc6a6p01";

              }
              { });

            megaparsec = fastHaskell (self.callHackageDirect
              {
                pkg = "megaparsec";
                ver = "9.2.0";
                sha256 = "0sn1ch4kgjrxcxl7kh6w8jywbh49mnhw1cbkqfz5992q0qvqpdyb";

              }
              { });


          };
        };

        # Override the version of dhall in dhallPackages
        # with the newer version of dhall
        dhallPackages = pkgs.dhallPackages.override {
          overrides = self: super: {
            dhall = haskellPackagesNewDhall.dhall;
            dhall-docs = haskellPackagesNewDhall.dhall-docs;
          };
        };

        # The package.dhall file uses the Dhall SemVer package,
        # which used v17 of the Dhall Prelude.
        # Here we make a derivation for this Prelude version.
        # The following is adapted from
        # https://nixos.org/manual/nixpkgs/stable/#ssec-dhall-overriding-dependency-versions
        dhallPrelude17 =
          dhallPackages.buildDhallGitHubPackage {
            name = "Prelude";
            githubBase = "github.com";
            owner = "dhall-lang";
            repo = "dhall-lang";
            rev = "v17.0.0";
            fetchSubmodules = false;
            sha256 = "0jnqw50q26ksxkzs85a2svyhwd2cy858xhncq945bmirpqrhklwf";
            directory = "Prelude";
            file = "package.dhall";
            source = false;
            document = false;
            dependencies = [ ];
          };

        dhallPrelude22 =
          dhallPackages.buildDhallGitHubPackage {
            name = "Prelude";
            githubBase = "github.com";
            owner = "dhall-lang";
            repo = "dhall-lang";
            rev = "v22.0.0";
            fetchSubmodules = false;
            sha256 = "157x95yw9hibpifa8figawgclnc1d1bapmbp1zw60l2viy936b83";
            directory = "Prelude";
            file = "package.dhall";
            source = false;
            document = false;
            dependencies = [ ];
          };

        dhallSemVer = dhallPackages.buildDhallGitHubPackage {
          name = "dhall-semver";
          githubBase = "github.com";
          owner = "Gabriel439";
          repo = "dhall-semver";
          rev = "2d44ae605302ce5dc6c657a1216887fbb96392a4";
          fetchSubmodules = false;
          sha256 = "0y8shvp8srzbjjpmnsvz9c12ciihnx1szs0yzyi9ashmrjvd0jcz";
          directory = "";
          file = "package.dhall";
          source = false;
          document = false;
          dependencies = [ dhallPrelude17 ];
        };


      in
      rec {

        # `nix build`
        packages = {
          check-dhall-lint = with haskellPackagesNewDhall;
            { src, file }:
            pkgs.stdenv.mkDerivation {
              name = "check-dhall";
              src = src;
              buildInputs = [ dhall ];
              buildPhase =
                ''
                  ${dhall}/bin/dhall lint --check --transitive ${file}
                '';
              installPhase =
                ''
                  touch $out
                '';
            };

          check-dhall-freeze = with haskellPackagesNewDhall;
            { src, file }:
            pkgs.stdenv.mkDerivation {
              name = "check-dhall";
              src = src;
              buildInputs = [ dhall ];
              buildPhase =
                ''
                  ${dhall}/bin/dhall freeze --check ${file}
                '';
              installPhase =
                ''
                  touch $out
                '';
            };

          SemVer = dhallSemVer;

          Prelude22 = dhallPrelude22;

          buildDhallPackage = dhallPackages.buildDhallPackage;

          buildDhallDirectoryPackage = dhallPackages.buildDhallDirectoryPackage;

          dhall-json = haskellPackagesNewDhall.dhall-json;

          dhall-toml = haskellPackagesNewDhall.dhall-toml;

          dhall-hpack-cabal = haskellPackagesNewDhall.dhall-hpack-cabal;

          dhall = haskellPackagesNewDhall.dhall;

        };

        packages.default = packages.check-dhall;

      });
}

Thank you! showConstructor is exactly the reason I needed the latest dhall version too! :slight_smile: