Let me try to answer your questions, or at least give you some pointers where you can find more information.
It appears that one of your derivations is just a normal Haskell derivation, and the other one is using developPackage.
Here’s a short overview of the different ways to produce a derivation with the Haskell stuff in Nixpkgs:
-
Most of the important Haskell-related files are in
pkgs/development/haskell-modules. And then pkgs/top-level/haskell-packages.nix sort of pulls everything together. -
Just like
stdenv,haskellPackagesprovides amkDerivationfunction.haskellPackagesalso provides acallPackagefunction that works similarly to the top-levelcallPackage. If you dig through the above files, you’ll find that they are defined here:-
Similarly to
stdenv.mkDerivation,haskellPackages.mkDerivationtakes an attribute set for building a Haskell package, and returns a derivation. It takes arguments likeisLibrary,executableHaskellDepends,pname, etc. Internally, it uses the builderpkgs/development/haskell-modules/generic-builder.nix. (This file is quite complex, but if you read through it, you can figure out exactly what happens with the values passed in asexecutableHaskellDepends. This generic Haskell builder is effectively a wrapper aroundstdenv.mkDerivationfor specifically building Haskell packages.) -
This is similar to the top-level
callPackage, but it knows about all the Haskell packages in the Nixpkgs Haskell package set. For example, you showed a Haskell derivation that started out like this:{ mkDerivation, aeson, base, cmdargs, directory, fetchgit, filepath, process, lens, lib, time}: mkDerivation { pname = "jot"; version = "1.4"; ...If you pass this function (or file) to
haskellPackages.callPackage, it knows how to automatically find the arguments for Haskell packages likeaeson,lens, etc. It also knows to fall back to looking for packages in the top-level Nixpkgs for things that aren’t Haskell libraries. So things likefetchgit,lib, etc will be pulled from the top-level Nixpkgs.
It is admittedly somewhat confusing that
haskellPackages.mkDerivationandstdenv.mkDerivationare named the same, but (completely) different functions (as well ascallPackage). -
-
This is a tool that reads a
.cabalfile and produces a function call like you have above. For instance:$ nix-shell -p cabal2nix --run 'cabal2nix https://github.com/mhwombat/jot.git' > my-haskell-package.nix $ cat my-haskell-package.nix { mkDerivation, base, cmdargs, directory, fetchgit, filepath, lib, process, time}: mkDerivation { pname = "jot"; version = "1.4"; ...You should be able to pass this package to
haskellPackages.callPackagein order to build it. For example:$ nix repl '<nixpkgs>' nix-repl> haskellPackages.callPackage ./my-haskell-package.nix {} «derivation /nix/store/zaimhwcg11z7z8r5g87m1hwwdiza5j84-jot-1.4.drv» nix-repl> :b haskellPackages.callPackage ./my-haskell-package.nix {} This derivation produced the following outputs: doc -> /nix/store/5pm4m9ml7pb3g5s9rs6vnm0wwy4rp9hp-jot-1.4-doc out -> /nix/store/8aq64ikzrllr8kll3sfmgbgdwzk48nzg-jot-1.4 -
The big problem with the
cabal2nixCLI tool is that you have to manually run it, redirect output to a file on disk, then callshaskellPackages.callPackageon that output.haskellPackages.callCabal2nixwraps up this whole process for you. For example:$ nix repl '<nixpkgs>' nix-repl> haskellPackages.callCabal2nix "jot" (builtins.fetchGit "https://github.com/mhwombat/jot.git") {} «derivation /nix/store/1wgfvjy7k3y66378214d9k3cwrp7z340-jot-1.4.drv» nix-repl> :b haskellPackages.callCabal2nix "jot" (builtins.fetchGit "https://github.com/mhwombat/jot.git") {} This derivation produced the following outputs: doc -> /nix/store/hfnfmv4sv0q5jhaq5yjrkysa4kiij54y-jot-1.4-doc out -> /nix/store/ckq3xw2qg696pm4iaclifzj7bjq0l3p2-jot-1.4This is a little easier than manually running
cabal2nix, and passing the output tohaskellPackages.callPackage.haskellPackages.callCabal2nixinternally uses IFD, with all its advantages and disadvantages. -
haskellPackages.developPackageThis is a function for easily doing Haskell development on a local package. With the
jotexample, this would be used for instance if you have thejotrepo checked out locally, and you want to jump into an environment withcabalavailable, as well as all the Haskell dependencies that are needed. There is a good example ofhaskellPackages.developPackageat the top of your first post.haskellPackages.developPackageis mostly a direct wrapper aroundhaskellPackages.callCabal2nix, but it has a little extra logic for giving you a development environment if you call it fromnix-shell.Example of building:
$ nix repl '<nixpkgs>' nix-repl> haskellPackages.developPackage { root = builtins.fetchGit "https://github.com/mhwombat/jot.git"; } «derivation /nix/store/0gx99ynmfkpn60bmr3jgm37vqn3v9ags-jot-1.4.drv» nix-repl> :b haskellPackages.developPackage { root = builtins.fetchGit "https://github.com/mhwombat/jot.git"; } This derivation produced the following outputs: doc -> /nix/store/wlrijn4irrpasam4kxk20rn5b8dnrpgi-jot-1.4-doc out -> /nix/store/7fgbai1xswflaw61wl9ccj1zf6k7vyi2-jot-1.4Quick example of shell environment:
$ nix-shell -E 'with import <nixpkgs> {}; haskellPackages.developPackage { root = builtins.fetchGit "https://github.com/mhwombat/jot.git"; }'We are now in a shell environment with a
ghcavailable that has all the dependencies ofjot. For example:$ ghc-pkg list | grep -i cmdargs cmdargs-0.10.21There is also a good explanation of using
developPackage, of which you’re likely aware
-
This is for creating a development environment that contains multiple Haskell packages. This is useful when you’re working on a “big” Haskell project, where you have a bunch of individual Haskell packages.
In general, you’d define each of your individual packages with
callCabal2nix, and then pass them all toshellFor. See the documentation ofhaskellPackages.shellForfor an example of this.
When doing development on Haskell packages locally, we generally recommend that users define an overlay for their local packages. The derivations for each of the local packages are generally defined with haskellPackages.callCabal2nix. Then haskellPackages.shellFor is used to define a shell environment.