Haskell pain points


#1

I’m totally new at Haskell, and I’m trying to start it using Nix. I was hoping to get some hints regarding these three issues I get.

what works

with import <nixpkgs> {};
let
  ghc = haskellPackages.ghcWithHoogle (ps: with ps; [
    protolude

    cabal-install hlint 
    hdevtools 
    stylish-haskell
    hindent
  ]);
in
stdenv.mkDerivation {
  name = "myenv";
  buildInputs = [ ghc ];
}

what doesn’t

ghc-mod

Adding ghc-mod to the package list I get:

Using Parsec parser
Configuring cabal-helper-0.8.1.2...
CallStack (from HasCallStack):
  die', called at ./Distribution/Simple/Configure.hs:958:20 in Cabal-2.2.0.1-FmPcs9btIHM2Dcb9OsF5gI:Distribution.Simple.Configure
  configureFinalizedPackage, called at ./Distribution/Simple/Configure.hs:462:12 in Cabal-2.2.0.1-FmPcs9btIHM2Dcb9OsF5gI:Distribution.Simple.Configure
  configure, called at ./Distribution/Simple.hs:596:20 in Cabal-2.2.0.1-FmPcs9btIHM2Dcb9OsF5gI:Distribution.Simple
  confHook, called at ./Distribution/Simple/UserHooks.hs:67:5 in Cabal-2.2.0.1-FmPcs9btIHM2Dcb9OsF5gI:Distribution.Simple.UserHooks
  configureAction, called at ./Distribution/Simple.hs:178:19 in Cabal-2.2.0.1-FmPcs9btIHM2Dcb9OsF5gI:Distribution.Simple
  defaultMainHelper, called at ./Distribution/Simple.hs:115:27 in Cabal-2.2.0.1-FmPcs9btIHM2Dcb9OsF5gI:Distribution.Simple
  defaultMain, called at Setup.hs:2:8 in main:Main
Setup: Encountered missing dependencies:
pretty-show >=1.8.1 && <1.9, temporary >=1.2.1 && <1.3

emailparse

Adding emailparse I get:

Setup: Encountered missing dependencies:
QuickCheck ==2.10.*,
base ==4.10.*,
either >=4.4.0 && <4.5,
tasty ==0.11.*,
tasty-hunit ==0.9.*,
tasty-quickcheck ==0.9.*

purebread-email

This library is, according to Hackage, provided in Nix, but I don’t find it in NixPackages.
Am I missing something?


I guess the first two problems can be solved by some overlay magic. I’d be grateful for an example on one of them, so then I can try my hands at the other.
The third, I can try to write my derivation, but I’m curious how the integration with Hackage is manager, and how tight it is.

Maybe a fourth question would be: are these typical problems I’d have also using just vanilla cabal and stack, or does Nix get in the way “a lot” usually?
I just don’t want to add Nix pain on top of the inevitable, though initial, Haskell pains :slight_smile:


#2
  1. ghc-mod is a problematic package because it only works under a very specific set of packages/ghc versions. I’m sure it is possible to get it to work but I’m not sure how exactly, sorry about that.

  2. emailparse looks like it is very precise about its dependencies. Specifying base = 4.10 means that the package only works with ghc-8.2.* but I imagine you are trying to build it with ghc-8.6.3. What I would try to do first would be to jailbreak the package. So something like

hp = haskellPackages.extend(self: super: { emailparse = haskell.lib.doJailbreak super.emailparse; } )

then

ghc = hp.ghcWithHoogle(...

If that doesn’t work, you can try disabled the testsuite as well with haskell.lib.dontCheck.

  1. purebread-email is packaged but your nixpkgs is too old to include it it seems as it was only uploaded towards the end of december. How old is your nixpkgs? The easiest thing to do would be to use a more recent nixpkgs if you can do that. Otherwise, one option is using cabal2nix as follows.
cabal2nix cabal://purebread-email > purebread-email.nix

Then in your file you can add it to the package set like

hp = haskellPackages.extend (self: super: { purebread-email = self.callPackage ./purebread-email.nix {}; } }

#3

That’s great, thank you.

(I just did a rebuild switch --upgrade of 18.09 to make sure I was reasonably “cutting-edge”.)

I’ll digest slowly :slight_smile:


#4

Awesome. Emailparse almost works, but there’s a compilation problem (see https://github.com/mkawalec/emailparse/issues/2 ), but purebred worked perfectly.

Would it be worth adding here


about extend and jailbreak?

Also, that page mentions several times that the default GHC version is 7.10 :stuck_out_tongue:


#5

You’ll find you can’t really use ghc-mod with any toolchain. It hasn’t released any versions compatible with GHCs newer than 8.0. The only way to get it for newer GHCs is to build the same git checkouts as haskell-ide-engine


#6

After some discussion on IRC and some issue browsing I ended up with this:

with import <nixpkgs> {};
let 
  hie = (import (builtins.fetchTarball {
    url = "https://github.com/domenkozar/hie-nix/tarball/master/domenkozar-hie-nix-19f47e0.tar.gz";
    sha256 = "1px146agwmsi0nznc1zd9zmhgjczz6zlb5yf21sp4mixzzbjsasq";
    }) {});
  hp = haskellPackages.extend(self: super: { 
    purebred-email = self.callPackage ./purebred-email.nix {};
  } );
  hpkgs = (ps: with ps; [
    protolude
    purebred-email
  ]);
  htools =  with hp; [
    cabal2nix
    cabal-install
    hlint 
    brittany
    hdevtools 
  ];
in
hp.shellFor {
  packages = hpkgs; 
  withHoogle = true;
  buildInputs = htools ++ [ hie.hie84 ];
  shellHook = ''
    export HIE_HOOGLE_DATABASE="$NIX_GHC_LIBDIR/../../share/doc/hoogle/index.html"
  '';
}

But still both hdevtools and hie seem not to be working (for a cabal project, no stack).

I get this from hie in ALE:

and hdevtools on the command line says:

Cabal error: hdevtools: Encountered missing dependencies:
protolude -any, purebred-email -any

#7

I don’t know how this hpkgs thing is meant to work. You need to add ghcWithPackages hpkgs to your buildInputs.


#8

Ooook, I totally misunderstood what shellFor is for. It didn’t help that I was using cabal new-build instead of build, I think :slight_smile:

But thanks! Now with this at least hie works (hdevtools doesn’t, but I prefer hie anyway):

with import <nixpkgs> {};
let 
  hie = (import (builtins.fetchTarball {
    url = "https://github.com/domenkozar/hie-nix/tarball/master/domenkozar-hie-nix-19f47e0.tar.gz";
    sha256 = "1px146agwmsi0nznc1zd9zmhgjczz6zlb5yf21sp4mixzzbjsasq";
    }) {});
  hp = haskellPackages.extend(self: super: { 
    purebred-email = self.callPackage ./purebred-email.nix {};
    root = self.callCabal2nix "root"  ./maildiffh.cabal {};
  });
  hpkgs = (ps: with ps; [
    cabal2nix
    cabal-install
    hlint 
    brittany
    hdevtools 
  ]);
  ghc = hp.ghcWithPackages( hpkgs );
in
  hp.shellFor {
    packages = p: with p; [ root ];
    buildInputs = with hp; [ ghc hie.hie84 ]; 
  }