Someone explain Haskell package management system

2.5k Views Asked by At

I just don't get it. It so confusing.

I got that there's ghc-pkg, and Cabal and cabal-install. And these are all different things.

I've been told that installing haskell-platform is a bad idea and it's better to get ghc and cabal-install separately. I don't know though why exactly is that a bad idea.

I found that there's a way to create a sandbox in a local folder using cabal sandbox init. But I don't know how to manage packages globally.

After installing ghc and cabal-install via brew, what's my next step should be? If I do cabal update it would create ~/.cabal directory and probably tell me to upgrade cabal-install by running
cabal install cabal-install. And then I'm gonna have to remove the one installed with brew, and add .cabal/bin to $PATH, so cabal would be pointing to the updated one. So does it mean now if I run cabal install ghc-mod while sitting in home dir it would install libraries in ~/.cabal folder? My ghc-pkg list pointing to /usr/local/Cellar/ghc/7.8.3/lib/ghc-7.8.3/package.conf.d and I don't like that. ghc-pkg list --user points to ~/.ghc/x86_64-darwin-7.8.3/package.conf.d and I don't like that either, but maybe that's fine. Anyway, what's the right way to initialize ghc-pkg? Should I run ghc-pkg init --global | --user or something?

Can you guys tell me what's the right way to manage global dependencies?

  • is it ok that package.conf.d and actual packages are sitting in different folders? What's the role of ~/.ghc folder and ~/.cabal folder?

  • How can one properly uninstall packages? ghc-pkg unregister does not remove the package, right?

    So let's say you installed a package that breaks with the latest version of some other package. Say monad-control. Let's say you do cabal install foo --constraint 'monad-control < 1.0.0.0' and that makes it work. Later you remove "foo" by running ghc-pkg unregister foo and by physically removing related files from .cabal/lib and package.conf.d folder (do you really have to do that manually?). Yet you still have old version of monad-control lying around now. Is there a way to find and prune unused packages?

  • How do you check for outdated packages?

  • Is there a way to see dependencies as a tree? ghc-pkg list gives you just flattened list of packages.

  • why ghc-pkg check throws bunch of warnings like that:

    Warning: haddock-interfaces: ~/.cabal/share/doc/x86_64-osx-ghc-7.8.3/haddock-api-2.15.0.1/html/haddock-api.haddock doesn't exist or isn't a file
    

    I know you can safely ignore those warnings, but what do they mean anyway?

  • finally, don't you guys ever feel that Haskell's packaging system kinda sucks? I know no one should ever criticize something without actually learning, and I am sorry for saying that. I am very newbie in Haskell, yet I feel default package management of Haskell is full of shortcomings. I'm wondering if there's better alternative that I don't know about? Haskell's been around for quite some time, I heard talks about package management that should not rely on concrete packages, but should be based on abstractions, like interfaces. Wondering, if soon we'd have this kind of packaging system? Or that's just theoretical academical rhetorics and that won't see the light until sometime in 2020?

1

There are 1 best solutions below

7
On

I would definitely recommend to install the Haskell Platform. It can be a PITA to update (at least on Mac), but it comes with batteries included and a lot of packages you wouldn't normally get (see System.Random for example).

ghc-pkg is often used to list installed packages.

cabal is used to distribute haskell packages. In practice it's used to build executables or install libraries. You can make a package by creating a .cabal file that will contain the recipe for building/installing your executable/library.

cabal-install is the package that updates cabal.

Sandboxes are extremely important (and they only come with the latests versions of cabal. They are basically like virtualenv for python. In general they create a virtual enviroment in which you can install all the libraries you want without polluting the global system-wide installations. To use them you just need to go into the root of the project you want to build and call cabal sandbox init and then you are done. You can just go on an use cabal install, cabal build, cabal configure, cabal test, like you would normally do. It will automatically detect that it's within a sandbox. If you screw something up you can just delete the sandbox via cabal sandbox delete.