on 899e933 help sign in
haskell.nix/docs/tutorials/development.md
203 lines 6.6 kB history raw
1Haskell.nix also provides reproducible development environments for
2your Haskell projects. These environments can contain not only GHC and
3your Haskell package dependencies, but also the required system
4libraries and build tools.
6Inside the development shell, you can run commands such as `ghc`,
7`ghci`, or `cabal new‑build` (`cabal build` on Cabal 3.0),
8and they will have all dependencies available.
10Every dependency will be cached in your Nix store. If you have set up
11Hydra CI, then your team can share pre-built dependencies.
13These examples assume that you have created your package set as
14described in [Creating Nix builds for your projects](getting-started.md) and
15it exists in a file called `default.nix`.
17!!! note
19 Old-style `cabal build` and `stack` builds are not (yet)
20 supported. For example, `stack` will (by design) download and
21 rebuild all dependencies, even though they are available in the
22 shell. However, if you have a Stack project, you can generate the
23 package set with Haskell.nix, then use `cabal new‑build` to work
24 on it. Starting Cabal 3.0 `cabal build` will work out of the box, as
25 new style builds are the default.
27## How to get a development shell
29If you have a Cabal or Stack project with one or more packages
30(i.e. multiple `.cabal` files, not a single package with multiple
31components), then you will need a development environment that
32contains the _dependencies_ of your packages, but not the packages
33themselves. This is what the [`shellFor`][shellFor] function does.
35```nix
36# shell.nix
37{ pkgs ? import <nixpkgs> {} }:
39let
40 hsPkgs = import ./default.nix { inherit pkgs; };
41in
42 hsPkgs.shellFor {
43 # Include only the *local* packages of your project.
44 packages = ps: with ps; [
45 pkga
46 pkgb
47 ];
49 # Builds a Hoogle documentation index of all dependencies,
50 # and provides a "hoogle" command to search the index.
51 withHoogle = true;
53 # You might want some extra tools in the shell (optional).
55 # Some common tools can be added with the `tools` argument
56 tools = { cabal = "3.2.0.0"; hlint = "2.2.11"; };
57 # See overlays/tools.nix for more details
59 # Some you may need to get some other way.
60 buildInputs = with pkgs.haskellPackages;
61 [ ghcid ];
63 # Prevents cabal from choosing alternate plans, so that
64 # *all* dependencies are provided by Nix.
65 exactDeps = true;
66 }
67```
69See also: [Haskell.nix Library Reference: `shellFor`][shellFor]
71[shellFor]: ../reference/library.md#shellfor
73## How to get a local Hoogle index
75If you need a local Hoogle for all the dependencies of your project create this file
77```nix
78# shell-hoogle.nix
79let
80 hsPkgs = import ./default.nix {};
81in
82 hsPkgs.shellFor {
83 packages = ps: [ps.my-package];
84 withHoogle = true;
85 }
86```
88and run `nix-shell shell-hoogle.nix --run "hoogle server --local"`.
89This will open a local Hoogle server at `http://127.0.0.1:8080`.
92## How to get an ad-hoc development shell including certain packages
94This creates a development environment with the given packages
95registered in the package database. The `ghcWithPackages` function
96operates on a Haskell.nix package set, and accepts an argument that
97selects packages from the larger package set.
99```nix
100# shell.nix
101let
102 haskellNix = import (builtins.fetchTarball https://github.com/input-output-hk/haskell.nix/archive/master.tar.gz) {};
103 nixpkgs = import haskellNix.sources.nixpkgs-1909 haskellNix.nixpkgsArgs;
104 haskell = nixpkgs.haskell-nix;
105in
106 haskell.haskellPackages.ghcWithPackages (ps: with ps;
107 [ lens conduit conduit-extra ])
108```
110If you need a Hoogle documentation index, use `ghcWithHoogle` in place
111of `ghcWithPackages`.
113## How to get packages from a certain Stackage snapshot
115Haskell.nix knows about every released Stackage snapshot. You can use
116it to build packages from a given snapshot, without setting up a full
117project.
119```nix
120let
121 haskellNix = import (builtins.fetchTarball https://github.com/input-output-hk/haskell.nix/archive/master.tar.gz) {};
122 nixpkgs = import haskellNix.sources.nixpkgs-1909 haskellNix.nixpkgsArgs;
123 haskell = nixpkgs.haskell-nix;
124in
125 haskell.snapshots."lts-13.18".alex.components.exes.alex
126```
128There are Haskell.nix package sets for every Stackage snaphot under
129`haskell.snapshots`.
131The alias `haskell.haskellPackages` corresponds to the package set for
132a recent LTS Haskell version.
134You can use `ghcWithPackages` on any of these package sets to quickly
135get a shell with some packages.
137!!! warning
138 The build will not work if your Nixpkgs does not contain the version
139 of GHC specified in the snapshot. Nixpkgs only carries the
140 latest version of each recent release series, so many snapshots
141 can't be built.
144## Emacs IDE support
146Once you have a development shell, then you can begin configuring
147Emacs to use it. The way I do it is:
1491. Run [lorri watch](https://github.com/target/lorri) to continuously
150 build the shell environment and maintain GC roots.
1522. Use [emacs‑direnv](https://github.com/wbolster/emacs-direnv) to
153 push the development environment into Emacs.
1553. Use [Dante](https://github.com/jyp/dante) for highlighting errors
156 and auto-completion. You must customize Dante to prevent it from
157 automatically using `nix‑shell` or `stack`. Trim `dante‑methods` to
158 just `new‑build` and `bare‑ghci`.
160 You can also use [`.dir‑locals.el`](https://www.gnu.org/software/emacs/manual/html_node/emacs/Directory-Variables.html)
161 for this. If your project has multiple targets, set `dante‑target`
162 per-directory.
1644. For [`haskell‑mode`](https://github.com/haskell/haskell-mode)
165 interactive Haskell, set `haskell‑process‑type` to
166 `cabal‑new‑repl`.
168## Using `nix repl`
170It's sometimes useful to load [Haskell.nix][] in the REPL to explore
171attrsets and try examples.
173```
174# example.nix
175{ nixpkgs ? <nixpkgs> }:
176rec {
177 haskell = import nixpkgs (import (builtins.fetchTarball https://github.com/input-output-hk/haskell.nix/archive/master.tar.gz) {}).nixpkgsArgs;
178 pkgNames = haskell.pkgs.lib.attrNames haskell.haskell-nix.snapshots."lts-13.18";
180```
182Load the example file:
184```
185$ nix repl '<nixpkgs>' example.nix
186Welcome to Nix version 2.3pre6631_e58a7144. Type :? for help.
188Loading '<nixpkgs>'...
189Added 10403 variables.
191Loading 'example.nix'...
192Added 2 variables.
194nix-repl> lib.take 5 pkgNames
195[ "ALUT" "ANum" "Allure" "Boolean" "BoundedChan" ]
197nix-repl>
198```
200Now that you have `nix-tools` and are able to import [Haskell.nix][],
201you can continue to the next chapter.
203[haskell.nix]: https://github.com/input-output-hk/haskell.nix