Simplest possible Haskell flake

I’m trying to create a flake to build the simplest possible Haskell project. It will be another tutorial in my nix-for-numbskulls series.

I’ve seen the example using cabal2nix, but I’d prefer to use the much simpler haskellPackages.developPackage, if possible. Here’s what I’ve got so far:

$ cat flake.nix
{
  description = "A flake for hello-haskell-flake";

  outputs = { self, nixpkgs }: {

    packages.x86_64-linux.hello = nixpkgs.legacyPackages.x86_64-linux.hello;

    defaultPackage.x86_64-linux = nixpkgs.haskellPackages.developPackage {
      root = ./.;
    };

  };
}

When I try to use this, I get an error that it can’t find haskellPackages

$ nix build
warning: creating lock file '/home/amy/flake-experiments/hello-haskell-flake/flake.lock'
warning: Git tree '/home/amy/flake-experiments/hello-haskell-flake' is dirty
error: attribute 'haskellPackages' missing

       at /nix/store/6l56yl4aq5zkin616aagagb5i0bk3sw6-source/flake.nix:8:35:

            7|
            8|     defaultPackage.x86_64-linux = nixpkgs.haskellPackages.developPackage {
             |                                   ^
            9|       root = ./.;

I’m guessing I need an import statement, but I’m not sure what to write. Is this even possible?

you have got to look into nixpkgs.legacyPackages.x86_64-linux.haskellPackages.

I think that line probably shouldn’t be there. So I read a bit more and this is my current flake.


$ cat flake.nix
{
  description = "A flake for hello-haskell-flake";

  inputs = {
    nixpkgs.url = "github:nixos/nixpkgs";
  };

  outputs = { self, nixpkgs }: {
    defaultPackage.x86_64-linux = nixpkgs.haskellPackages.developPackage {
      root = ./.;
    };
  };
}

But I’m still getting the error about haskellPackages being missing, and I don’t know how to fix it.

$ nix build
error: attribute 'haskellPackages' missing

       at /nix/store/dvaq3vwwqphr0pyjl28ap4r9n7iisqgj-source/flake.nix:9:35:

            8|   outputs = { self, nixpkgs }: {
            9|     defaultPackage.x86_64-linux = nixpkgs.haskellPackages.developPackage {
             |                                   ^
           10|       root = ./.;

I tried using an import…

$ cat flake.nix
{
  description = "A flake for hello-haskell-flake";

  inputs = {
    nixpkgs.url = "github:nixos/nixpkgs";
  };

  outputs = { self, nixpkgs }: {
    defaultPackage.x86_64-linux =
      let
        pkgs = import <nixpkgs> { };
      in
        pkgs.haskellPackages.developPackage {
          root = ./.;
        };
  };
}

But I got this error…

$ nix build
error: cannot look up '<nixpkgs>' in pure evaluation mode (use '--impure' to override)

       at /nix/store/w7sbcj28gkzps7x1ysvzn4sd3g9pnb1i-source/flake.nix:11:23:

           10|       let
           11|         pkgs = import <nixpkgs> { };
             |                       ^
           12|       in
(use '--show-trace' to show detailed location information)

So I tried…

$ nix build --impure
error: builder for '/nix/store/1n0lk1cd5w5nnandy6d29rfq6rrwc8gz-hello-haskell-flake-0.1.0.0.drv' failed with exit code 1;
       last 10 log lines:
       >   $, called at libraries/Cabal/Cabal/Distribution/Simple/Configure.hs:1024:20 in Cabal-3.2.1.0:Distribution.Simple.Configure
       >   configureFinalizedPackage, called at libraries/Cabal/Cabal/Distribution/Simple/Configure.hs:477:12 in Cabal-3.2.1.0:Distribution.Simple.Configure
       >   configure, called at libraries/Cabal/Cabal/Distribution/Simple.hs:625:20 in Cabal-3.2.1.0:Distribution.Simple
       >   confHook, called at libraries/Cabal/Cabal/Distribution/Simple/UserHooks.hs:65:5 in Cabal-3.2.1.0:Distribution.Simple.UserHooks
       >   configureAction, called at libraries/Cabal/Cabal/Distribution/Simple.hs:180:19 in Cabal-3.2.1.0:Distribution.Simple
       >   defaultMainHelper, called at libraries/Cabal/Cabal/Distribution/Simple.hs:116:27 in Cabal-3.2.1.0:Distribution.Simple
       >   defaultMain, called at /nix/store/4mdp8nhyfddh7bllbi7xszz7k9955n79-Setup.hs:2:8 in main:Main
       > Setup: Encountered missing or private dependencies:
       > hello-haskell-flake -any
       >
       For full logs, run 'nix log /nix/store/1n0lk1cd5w5nnandy6d29rfq6rrwc8gz-hello-haskell-flake-0.1.0.0.drv'.

I have no idea where to go from here.

You are importing <nixpkgs> (which does a lookup in NIX_PATH and is completely independent from the nixpkgs variable in scope) instead of plain nixpkgs.

There seems to have been a recent thread on the topic of legacyPackages/import:

2 Likes

Thank you, that makes sense.

I’ve also just realised that the cabal2nix approach is much easier than I thought, and should meet my needs. At first, I was put off by the mere mention of cabal2nix because when I used it (back in ye olden days), you had to run it every time you modified your cabal file. That’s why I switched to developPackage in the first place. Reading more carefully, I now understand that the flake will call cabal2nix for me; I just set it up and forget it.

2 Likes

Well this is no different from running it manually, you can just use nix (via import from derivation) to run cabal2nix in a derivation for you. That possibility has been around for quite some time (in fact it’s used by developPackage internally), but comes with its own disadvantages (mainly negatively impacting eval time).

2 Likes