{
# Reuse any local nixpkgs, at cost of reproductibility
#inputs.nixpkgs.url = "flake:nixpkgs";
# Can be overriden by passing --override-input nixpkgs flake:nixpkgs to nix
inputs.nixpkgs.url = "github:NixOS/nixpkgs/8585991bfb629edda1e42c191bef935d9d70d690";
inputs.flake-utils.url = "github:numtide/flake-utils";
outputs = inputs: inputs.flake-utils.lib.eachDefaultSystem (system: let
  inherit (pkgs.lib) listToAttrs nameValuePair;
  pkgs = inputs.nixpkgs.legacyPackages.${system};
  ghc = null; # Use default ghc, but could have been ghc901
  haskellPackages =
    if ghc == null
    then pkgs.haskellPackages
    else pkgs.haskell.packages.${ghc};
  days = [ "04" "05" "06" "07" ];
  hs = haskellPackages.extend (with pkgs.haskell.lib;
    hfinal: hprev:
      listToAttrs (map (day: nameValuePair
        "AoC2020${day}" (hfinal.callCabal2nix "AoC2020" (./. + "/Day"+day) {})
      ) days)
  );
  in rec {
    devShell = hs.shellFor {
      packages = ps: map (day: ps."AoC2020${day}") days;
      withHoogle = false;
      nativeBuildInputs = [
        hs.cabal-install
        hs.haskell-language-server
        #hs.hpc
      ];
      buildInputs = [
        #hs.ghcid
        #hs.ormolu
        #hs.hlint
        #pkgs.nixpkgs-fmt
      ];
    };
    packages = listToAttrs (map (day: nameValuePair "Day${day}" hs."AoC2020${day}") days);
    defaultApp = {
      type = "app";
      program = (pkgs.writeShellScript "run" ''
        cd ${inputs.self}
        ${pkgs.gnumake}/bin/make run
      '').outPath;
    };
    apps = listToAttrs (map (day: nameValuePair "Day${day}" {
      type = "app";
      program = "${packages."Day${day}"}/bin/Day";
    }) days);
  }
);
}