How can I install a Haskell library to be accessible via GHCi with Nixos? - haskell

I've managed to install ghc with nix-env -i ghc.
I'd like to install a Haskell library now, how should this be done? For example the turtle (https://hackage.haskell.org/package/turtle) library.
I've run nix-env -f "<nixpkgs>" -iA haskellPackages.turtle, however running ghci and import Turtle fails:
Prelude> import Turtle
<no location info>: error:
Could not find module ‘Turtle’
It is not a module in the current program, or in any known package.
Output of ghc-pkg list:
/nix/store/fvf278s3lqsjv488ahhdi8jx6i0qzsr9-ghc-8.0.2/lib/ghc-8.0.2/package.conf.d
Cabal-1.24.2.0
array-0.5.1.1
base-4.9.1.0
binary-0.8.3.0
bytestring-0.10.8.1
containers-0.5.7.1
deepseq-1.4.2.0
directory-1.3.0.0
filepath-1.4.1.1
ghc-8.0.2
ghc-boot-8.0.2
ghc-boot-th-8.0.2
ghc-prim-0.5.0.0
ghci-8.0.2
haskeline-0.7.3.0
hoopl-3.10.2.1
hpc-0.6.0.3
integer-gmp-1.0.0.1
pretty-1.1.3.3
process-1.4.3.0
rts-1.0
template-haskell-2.11.1.0
terminfo-0.4.0.2
time-1.6.0.1
transformers-0.5.2.0
unix-2.7.2.1
xhtml-3000.2.1

This works differently on NixOS because of purity. NixOS' GHC will only look at its own immutable installation directory and the packages that have been installed by the user with cabal install.
What you can do is install into your user profile a GHC wrapper that supplies a nice set of packages when you run ghci.
Create a file my-ghc.nix:
(import <nixpkgs> {}).haskellPackages.ghcWithPackages (hpkgs: with hpkgs; [
lens
aeson
turtle
])
Uninstall your previous attempt, to avoid name collisions:
nix-env -e ghc turtle
Install the wrapped GHC:
nix-env -if my-ghc.nix
You may edit the file in the future and re-run that command.
When I am working on a project, I prefer to use cabal2nix and nix-shell. (For an introduction, see Oliver Charles' blog post)

As an alternative Robert's answer, one can use a nix-shell environment by creating a shell.nix file with contents of:
{ pkgs ? import <nixpkgs> {} }:
let myGhc = pkgs.haskellPackages.ghcWithPackages (hpkgs: with hpkgs; [
turtle
]);
in
pkgs.mkShell {
buildInputs = [ myGhc ];
}
And entering this environment with nix-shell.
Alternatively this single command nix-shell -p "haskellPackages.ghcWithPackages (pkgs: [pkgs.turtle])".

Related

Why can't the ghc (Haskell) compiler find the module Data.Vector which I have imported? I get the error: Could not find module 'Data.Vector'

vector module has been installed by "cabal install vector"
bash-3.2$ ghc-pkg list -f $HOME/.cabal/store/ghc-9.2.1/package.db
/Users/gcolpitts/.cabal/store/ghc-9.2.1/package.db
primitive-0.7.3.0
vector-0.12.3.1
but the compiler can't find it:
$ ghc prob214ff.hs
[1 of 1] Compiling Main ( prob214ff.hs, prob214ff.o )
prob214ff.hs:14:1: error:
Could not find module ‘Data.Vector’
Perhaps you meant Data.Functor (from base-4.16.0.0)
Use -v (or `:set -v` in ghci) to see a list of the files searched for.
|
14 | import Data.Vector
Thx #n. 1.8e9-where's-my-share !
ghc -package-db $HOME/.cabal/store/ghc-9.2.1/package.db prob214ff.hs
solves my problem although it is a regression from previous versions of ghc which didn't require the use of the -package-db option.
I'd love to use GHC_PACKAGE_PATH but I can't see how to make that work. Sec 5.9.5 of the ghc users guide is confusing. It states "A package database is where the details about installed packages are stored. It is a directory, usually called package.conf.d." i.e. not the package.db file that I gave with -package-db on the command line. But where is the package.conf.db directory with info on the vector package that I installed with cabal?
"ghc-pkg list" references /usr/local/lib/ghc-9.2.1/lib/package.conf.d but the output of the command doesn't list the vector package I installed.
"ghc-pkg list -f $HOME/.cabal/store/ghc-9.2.1/package.db" does list the vector package in it's output but doesn't tell me a package.conf.d directory that knows about the vector package.
This is a bit fiddly with cabal version 2. Installing packages no longer really makes sense (despite the cabal install still existing...). Instead you will probably find it easiest to create a cabal package instead, for example:
$ mkdir my-package
$ cd my-package
$ cabal init
<Edit my-package.cabal and add vector to the build-depends line>
<Put the contents of prob214ff.hs in app/Main.hs instead>
$ cabal run
This will be fixed in 9.2.2, see https://gitlab.haskell.org/ghc/ghc/-/issues/20660#note_391573

Haskell timeit Module - SystemTimeIT not found

This must be very simple; but why this error:
PS C:\Users\guthrie\Desktop> cabal install --lib timeit
Resolving dependencies...
Up to date
PS C:\Users\guthrie\Desktop> ghci
GHCi, version 8.10.2: https://www.haskell.org/ghc/ :? for help
Prelude> :m System.TimeIt
<no location info>: error:
Could not find module `System.TimeIt'
Perhaps you meant System.Timeout (from base-4.14.1.0)
Prelude>
Leaving GHCi.
Hackage shows System.TimeIt as being defined in timeit-2.0, which is what cabal installed.
PS C:\Users\guthrie\Desktop> cabal install timeit
Resolving dependencies...
Build profile: -w ghc-8.10.2 -O1
In order, the following will be built (use -v for more details):
- timeit-2.0 (lib) (requires download & build)
Downloading timeit-2.0
Downloaded timeit-2.0
Starting timeit-2.0 (lib)
Building timeit-2.0 (lib)
Installing timeit-2.0 (lib)
Completed timeit-2.0 (lib)
Checking again:
PS C:\Users\guthrie\Desktop> cabal install --lib timeit
Resolving dependencies...
Up to date
But trying to check on it from cabal info::
PS C:\Users\guthrie\Desktop> cabal info timeit
* timeit (library)
Synopsis: Time monadic computations with an IO base.
Versions available: 0.9.0.0, 1.0.0.0, 2.0
Versions installed: [ Not installed ]
Homepage: https://github.com/merijn/timeit
Bug reports: https://github.com/merijn/timeit/issues
Description: A simple wrapper to show the used CPU time of monadic
computation with an IO base.
Category: System
License: BSD3
Author: Lennart Augustsson
Maintainer: Merijn Verstraaten <merijn#inconsistent.nl>, Lennart Augustsson
Source repo: ssh://github.com:merijn/timeit.git
Dependencies: base >=3 && <5, transformers >=0.2 && <0.6
Cached: Yes
Modules:
System.TimeIt
So it reports: "Not installed".
Same problem with criterion (Criterion.Main).
I see a note from 2/2020; that if a package is installed without the --lib option,
It does add the library to the package db in this case but does not
add it to the default environment.
(*https://github.com/haskell/cabal/issues/6262#issuecomment-589843722)
So I repeated the install with this option, no effect - just reported "Up to date".
That same link gave a solution (work-around?) to use instead cabal v1-install, which does work. But what would be the recommended simple solution to be able just to use ghci for testing small codes? Forced migration to stack, with local sandboxed and copies of everything for every small test?
Since I am only doing very simple short tests of examples, I was not creating a sandbox for each, and do not have a .cabal file, are those now necessary?!
(cabal 3.2.0.o, ghc 8.10.2, Windows 10)
I strongly recommend that you don't try to use ghc and ghci directly but instead use cabal. If you want to quickly play around with timeit in the REPL then use
cabal v2-repl --build-depends timeit
If you want to do anything more complicated then create a (perhaps temporary) project and add timeit as a dependency:
$ mkdir my-temporary-package
$ cd my-temporary-package
$ cabal init
Edit my-temporary-package.cabal to change
build-depends: base >=... && <...
to
build-depends: base, timeit
(The constraints on base are going to cause you more harm than good for a quick exploratory project. You can add them back later if it becomes necessary.) Then
$ cabal v2-repl
will get you a REPL with timeit available.

Haskell packages not listed in ghc-pkg when installed through Nix

I have installed GHC through Nix:
$ nix-env -i ghc
Then I have installed the aeson package:
$ nix-env -f "<nixpkgs>" -iA haskellPackages.aeson
And pointed GHC to the Nix package folder:
$ export GHC_PACKAGE_PATH=~/.nix-profile/lib/ghc-8.0.1/package.conf.d/
Which seems to work:
$ ghc-pkg list
/Users/zoul/.nix-profile/lib/ghc-8.0.1/package.conf.d
Cabal-1.24.0.0
array-0.5.1.1
…
But the aeson package is missing from the list of packages above and can’t be loaded. Even though there’s clearly something there:
$ ls /Users/zoul/.nix-profile/lib/ghc-8.0.1/ | grep ^ae
aeson-0.11.2.1
What am I doing wrong?
You cannot install Haskell libraries in Nix that way because the ghc compiler you're using does not search your user's profile for libraries. Consequently, installing a library there has no effect. This topic is explained in great detail in the Nixpkgs user manual. I'm citing the relevant bit from "8.5.2.2. How to install a compiler with libraries":
GHC expects to find all installed libraries inside of its own lib directory. This approach works fine on traditional Unix systems, but it doesn’t work for Nix, because GHC’s store path is immutable once it’s built. We cannot install additional libraries into that location. As a consequence, our copies of GHC don’t know any packages except their own core libraries, like base, containers, Cabal, etc.
We can register additional libraries to GHC, however, using a special build function called ghcWithPackages. That function expects one argument: a function that maps from an attribute set of Haskell packages to a list of packages, which determines the libraries known to that particular version of GHC. For example, the Nix expression ghcWithPackages (pkgs: [pkgs.mtl]) generates a copy of GHC that has the mtl library registered in addition to its normal core packages:
$ nix-shell -p "haskellPackages.ghcWithPackages (pkgs: [pkgs.mtl])"
[nix-shell:~]$ ghc-pkg list mtl
/nix/store/zy79...-ghc-7.10.2/lib/ghc-7.10.2/package.conf.d:
mtl-2.2.1
This function allows users to define their own development environment by means of an override. After adding the following snippet to ~/.nixpkgs/config.nix,
{
packageOverrides = super: let self = super.pkgs; in
{
myHaskellEnv = self.haskell.packages.ghc7102.ghcWithPackages
(haskellPackages: with haskellPackages; [
# libraries
arrows async cgi criterion
# tools
cabal-install haskintex
]);
};
}
it’s possible to install that compiler with nix-env -f "<nixpkgs>" -iA myHaskellEnv.

Installation of Haskell Package Euterpea fails on NixOs

Unfortunately, the installation of the haskell package 'Euterpea' fails on NixOS:
The Nixpkgs manual states that all haskell packages registered on hackage (which the Euterpea package is) are included in the nix package manager and have to be installed like this:
nix-env -f "<nixpkgs>" -iA haskellPackages.Euterpea
After some downloading and compiling, the following error occurs, and the process is interrupted:
[ 7 of 46] Compiling Euterpea.IO.MIDI.MidiIO ( Euterpea/IO/MIDI/MidiIO.lhs, dist/build/Euterpea/IO/MIDI/MidiIO.o )
Euterpea/IO/MIDI/MidiIO.lhs:153:25:
Not in scope: ‘Heap.extractHead’
Euterpea/IO/MIDI/MidiIO.lhs:160:34: Not in scope: ‘Heap.head’
builder for ‘/nix/store/wc8d02s0kin4l0siwixlylssizfsrzgx-Euterpea-1.1.1.drv’ failed with exit code 1
error: build of ‘/nix/store/wc8d02s0kin4l0siwixlylssizfsrzgx-Euterpea-1.1.1.drv’ failed
Does anyone have an idea how to fix this?
The problem here is that Euterpea does not compile against the more-recent versions of its dependencies available in nixpkgs. Here is an expression that can succcessfully build Euterpea (tested on current nixpkgs unstable):
Write the following nix expression into a file called euterpea.nix:
# let's get nixpkgs into scope
with (import <nixpkgs> {});
let
lib = haskell.lib;
# build a "package set" (collection of packages) that has the correct versions of the dependencies
# needed by Euterpea
customHaskellPackages = haskellPackages.override (old: {
overrides = self: super: {
heap = self.callHackage "heap" "0.6.0" {};
PortMidi = self.callHackage "PortMidi" "0.1.5.2" {};
stm = self.callHackage "stm" "2.4.2" {};
};
});
in {
# this is a ghc wrapper that has only Euterpea as its visible packages
ghc = customHaskellPackages.ghcWithPackages (pkgs: [ pkgs.Euterpea ]);
# this is just the output of the build for Euterpea
pkg = customHackagePackages.Euterpea;
# for convenience, also expose the package set that we build against
pkgset = customHaskellPackages;
}
Then you can run the following commands:
$ nix-build euterpea.nix -A ghc # build a GHC with the Euterpea package included
/nix/store/mjlp6rxcsiv5w8ay1qp0lrj8m40r3cyl-ghc-8.0.1-with-packages
$ result/bin/ghci # result contains a GHC installation that has Euterpea, so we can run GHCI from it
GHCi, version 8.0.1: http://www.haskell.org/ghc/ :? for help
Loaded GHCi configuration from /home/.ghci
λ: import Euterpea
λ:
Leaving GHCi.
$ nix-env --install --file euterpea.nix -A ghc # we can also install this ghc into our user environment
installing ‘ghc-8.0.1-with-packages’
building path(s) ‘/nix/store/7jwrwxaxyig6hf747rsan5514gw7qi51-user-environment’
created 5840 symlinks in user environment
$

ghc-mod can't find a user installed module

I have a situation where ghc-mod can't find a module installed in my ~/.ghc/ directory.
The program (foo.hs) is just:
import Control.Monad.Loops
main = undefined
ghci loads foo.hs without any errors.
ghc-pkg list produces the output:
/Library/Frameworks/GHC.framework/Versions/7.8.3-x86_64/usr/lib/ghc-7.8.3/package.conf.d
Cabal-1.18.1.4
GLURaw-1.4.0.1
...
~/.ghc/x86_64-darwin-7.8.3/package.conf.d:
...
monad-loops-0.4.2.1
but ghc-mod check foo.hs errors out with:
x.hs:4:8:Could not find module ‘Control.Monad.Loops’Perhaps you meant Control.Monad.Cont (from mtl-2.1.3.1) Control.Monad.List (from mtl-2.1.3.1) Control.Monad.Trans (from mtl-2.1.3.1)Use -v to see a list of the files searched for.
ghc-mod is located in ~/Library/Haskell/bin and ghc-mod -v emits:
ghc-mod version 5.0.1.2 compiled by GHC 7.8.3
...
What's kinda odd is that I don't get an error when loading foo.hs in Emacs under haskell-mode, and presumable that also uses ghc-mod.
Is there a way to debug this further and/or configure ghc-mod to look in my ~/.ghc directory?
The answer is that ghc-mod will look for a cabal.sandbox.config file in all parent directories of the current working directory and use that if it finds one, and that was hiding my ~/.ghc package directory.

Resources