4

What's the shortest shell.nix equivalent of the following cmdline arguments?

nix-shell -p "haskell.packages.ghc865.ghcWithPackages (p: [p.ghci-pretty])"

This works, but it's verbose:

# contents of shell.nix file
# run with the following cmd:
# nix-shell shell.nix
{ nixpkgs ? import <nixpkgs> {} }:
let
  inherit nixpkgs;
  inherit (nixpkgs) haskellPackages;
  haskellDeps = a: with a; [
    ipprint
    base
    hscolour
    ghci-pretty
  ];
  ghc = nixpkgs.haskellPackages.ghcWithPackages haskellDeps;

  nixPackages = [
    haskellPackages.cabal-install
    ghc
  ];
in
nixpkgs.stdenv.mkDerivation {
  name = "profile_name";
  buildInputs = nixPackages;
}
v217
  • 765
  • 1
  • 6
  • 17
  • Don't extend your question with comments; edit the question itself. That said, is your comment supposed to be an answer, or are you looking for something shorter than what is in your comment? – chepner Oct 07 '19 at 13:05
  • Why did you delete your first comment, only to add a second? Code in a comment is virtually unreadable. *Add your attempt to the question itself.* – chepner Oct 07 '19 at 13:11
  • This works, but it's verbose: ``` # contents of shell.nix file # run with the following cmd: # nix-shell shell.nix { nixpkgs ? import {} }: let inherit nixpkgs; inherit (nixpkgs) haskellPackages; haskellDeps = a: with a; [ ipprint base hscolour ghci-pretty ]; ghc = nixpkgs.haskellPackages.ghcWithPackages haskellDeps; nixPackages = [ haskellPackages.cabal-install ghc ]; in nixpkgs.stdenv.mkDerivation { name = "profile_name"; buildInputs = nixPackages; } ``` – v217 Oct 07 '19 at 13:15
  • Sorry newlines don't seem to appear. – v217 Oct 07 '19 at 13:16
  • Edit the question. Stop trying to put code in a comment. – chepner Oct 07 '19 at 13:17
  • I need the file shell.nix version for use in vscode. – v217 Oct 07 '19 at 13:39
  • 1
    Any chance this is a shell for a project built with cabal2nix? – Robert Hensing Oct 07 '19 at 17:17
  • @RobertHensing I guess I found the shell.nix template on the nixos website. I have not written it myself. I am new to nix. It's really great to have those binary prebuilt haskell packages, but to have a proper language just to install packages?... Anyway I found no simpler solution. – v217 Oct 08 '19 at 11:42
  • 1
    What is the goal why you need a shell with ghc? – Robert Hensing Oct 09 '19 at 06:52
  • @RobertHensing vscode recognises the shell.nix file. (You have to install the nix extension.) This is rather slow, but it works. – v217 Oct 09 '19 at 07:52
  • 1
    Unless you want to integrate this shell.nix more tightly with other Nix files, this is about as short as it gets. (except for inlining, etc) If you're going to package your project with Nix, you may reuse some of that code, but we'll need an example of the packaging to work with. I hope Nix packaging methods for standalone projects can converge at some point... – Robert Hensing Oct 09 '19 at 16:04
  • @RobertHensing I am new to Nixpackaging. Right now nix-shell startup times are acceptable, but I am worried that when I add more dependencies startup times will be worse. I use only one shell.nix file. Can I persist the changes made by nix-shell shell.nix somehow globally? – v217 Oct 10 '19 at 09:22
  • 1
    Typically the added overhead per dependency is insignificant because most of its closure overlaps the closure before adding it. If you want to speed up startup, you can try [lorri](https://github.com/target/lorri), although that's a bit experimental as of Oct 2019. – Robert Hensing Oct 10 '19 at 18:53

1 Answers1

6

You can just copy your command line verbatim like so:

{ pkgs ? import <nixpkgs> {} }:
let
  ghc = pkgs.haskell.packages.ghc865.ghcWithPackages (p: [ p.ghci-pretty ]);
in
pkgs.mkShell {
  buildInputs = [ ghc ];
}
nrdxp
  • 674
  • 7
  • 12
  • Thanks! Is there a concise way to select the default ghc version? – v217 Oct 12 '19 at 10:23
  • I jus't found ghcHEAD with this command: `nix-env -qaP -A nixpkgs.haskell.compiler` – v217 Oct 12 '19 at 10:37
  • And there is `nix-env -qaP -A nixpkgs.ghc` – v217 Oct 12 '19 at 10:55
  • This works even though I don't know why so far `{ a ? import {} }: let inherit a; inherit (a) haskellPackages; c = a.haskellPackages.ghcWithPackages (b: with b; [ shh shh-extras # pipes Glob hoogle ghci-pretty ]); in a.mkShell { buildInputs = [ c ]; }` I used the not very descriptive variable names `a`,`b`,`c` so that it's clear for a beginner that those are variable names and not something builtin to nix. – v217 Oct 12 '19 at 11:37
  • The first inherit statement is apparently not necessary `{ a ? import {} }: let inherit (a) haskellPackages; c = a.haskellPackages.ghcWithPackages (b: with b; [ shh shh-extras # pipes Glob hoogle ghci-pretty ]); in a.mkShell { buildInputs = [ c ]; }` – v217 Oct 12 '19 at 11:43
  • You could actually get rid of all inherit statements like so `{ pkgs ? import {}, ghc ? pkgs.ghc.withPackages (p: [ p.ghci-pretty ])}:` If you just want default ghc this is a bit shorter and saves a few lines. then you just have to `pkgs.mkShell { buildInputs = [ghc];` } – nrdxp Oct 13 '19 at 07:40