How to install an library in Haskell? - haskell

I try to use
Control.Monad.Extra.andM
import Control.Monad.Extra (andM)
but has an error:
Could not find module ‘Control.Monad.Extra’
Perhaps you meant
Control.Monad.Catch (needs flag -package-key exceptions-0.10.4)
Control.Monad.Error (needs flag -package-key mtl-2.2.2)
Control.Monad.Except (needs flag -package-key mtl-2.2.2)not found
This error does not make sense.
According to
https://cabal.readthedocs.io/en/3.6/installing-packages.html#installing-packages-from-hackage
3.2.1. Installing packages from Hackage
The cabal tool also can download, configure, build and install a Hackage package and all of its dependencies in a single step. To do this, run:
$ cabal install [PACKAGE...]
To browse the list of available packages, visit the Hackage web site.
Which says "in a single step", but in my experience this is too complicated and actually I have no idea how to install Control.Monad.Extra .
Usually, when a Haskeller want to install a specific library/package like this, how do you do this? There's no adequate documentations, it seems.

How to install an library in Haskell?
You don't. You should just depend on them, and then let Cabal worry about any installations that may need to be done. I.e., as you wrote
Go to the Hackage page and study which exact library to be used.
*.cabal file -> build-depends: extra >=1.7.10
This is the crucial step. Your own Cabal file is the way to both specify what libraries are needed right now, as well as ensuring that everything will still work in the future. This file needs to specify both the packages you require, as well as the modules you're defining yourself.
Probably you don't actually need >=1.7.10, but it can't hurt much to be specific there. Standard practice is to add both lower and upper bounds on the x.y level, i.e. you'd use extra >=1.7 && <1.8, and then push the upper boundary as new versions come out. Arguably this is a bit overcautious; if you only use some simple tools from a package that is unlikely to have breaking changes in the future then it may be less trouble to just leave the upper boundary out.
$ cabal install extra
You've already specified that extra is needed for your project, no need to state that again. Instead, simply build your own project now.$ cabal buildor, to get a GHCi prompt with your modules,$ cabal replor, if you have an executable with a main that you wish to execute$ cabal runor if you want to install that executable (and only then)$ cabal installCabal will then automatically figure out that extra-1.7.10 should be installed first.
(In old Cabal it would still have been necessary to run cabal install --dependencies-only first.)

Ok Self-Answered. Comment me if the information is wrong.
1. Go to the Hackage page and study which exact library to be used.
In this case, it seems extra-1.7.10.
2. *.cabal file -> build-depends: extra >=1.7.10 (among other libs)
3. $ cabal install extra
Error:
cabal: Cannot build the executables in the package extra because it does not contain any executables. Check the .cabal file for the package and make sure that it properly declares the components that you expect.
Well, I did for sure.
4. cabal install extra --lib
Finally works, but the documentation never said this.
Am I correct?
`
Is this the only method? or any other smarter way?

Related

Cabal - add build dependency with Cabal instead of manually mangling with the file

Do I need to manually edit the *.cabal file's build-depends section to add package as a project dependency?
Or perhaps there is a more convenient way that is not as error prone as manually mangling with build files is.
Thinking about functionality that pretty much any package manager I used has, namely
apt install
npm i
nuget install
Install Package
and so on. Does such functionality exist in Cabal?
There is no better way at the moment. The answer #danidiaz gave is essentially correct -- cabal-edit will automatically update cabal files for you. The plan is to import similar functionality into cabal directly. This was remains blocked on an exactprinter that can parse and emit cabal files precisely -- and work on that exactprinter is now underway.

Will users be diverted from a package if it's not passing `cabal check` for `cabal` `1.22` due to the absence of `Setup.hs`?

stack new usually creates a default Setup.hs file. I removed it from a project and it still builds alright for any lts resolver down to lts-2. It also passes cabal check at least for cabal version 1.24. (Though not for cabal 1.22.)
Can I conclude from this result that including a default Setup.hs in a project is not trendy anymore and I can drop it? In particular, will many prospective users be diverted from installing the package if it's not passing cabal check for cabal 1.22?
P.S. This question is more specific than the other, similar one in that I want to know, specifically, if the package not passing cabal check for a certain version of cabal due to the absence of an otherwise unnecessary Setup.hs will be counted against that package in some situations, and whether there are any other downsides to not having a Setup.hs in a project, considering the current state of the Haskell ecosystem. Whether a Setup.hs is necessary or useful overall is not a question here.
If you run cabal sdist on a project without a Setup.hs file, cabal creates one for you -- try it!
As such, there's no point to removing the file, because it will just get regenerated when you package for distribution anyway.

What exactly does cabal install --avoid-reinstalls do?

I've found --avoid-reinstalls makes packages build where otherwise cabal fails. What exactly is it doing? Doesn't cabal already try to avoid reinstalls, or shouldn't it?
This mailinglist post explains it pretty well: http://www.haskell.org/pipermail/beginners/2011-June/007502.html
The dependency resolution algorithm will try to make a consistent
install plan that allows gitit to be run. However, in order to achieve
that, it may decide that it's necessary to reinstall some existing
packages in a new configuration (with other dependency or flag
settings). Such reinstalls will then overwrite the previous package in
the store, and if that previous package was depended on by something
else, these other things will break.
The --avoid-reinstalls flag prevents exactly this behavior.

cabal build-depends: how to find?

How can I find out what needs to go into the module.cabal build-depends? I mean, some modules may already be part of the Haskell platform whilst others may not? How to I find out/know what I must write here so that the module I offer will install with cabal on the majority of Haskell installations "out there"?
My situation is that I have it working on my systems, but cannot remember for what import I actually had to install an other module and what was part of the Haskell Platform that I use. How do I now best find the way from my situation to a cabal installable package?
If you use Cabal to build your project, it will only look at the modules listed in the .cabal file, even if you have other modules installed locally.
So all you have to do is run it as is (with nothing in the depends declaration) and it will give you an error for each module you need to specify. I think the error even tells you the name of the package.

Using the --reinstall flag with cabal-dev

I'm working on the wxHaskell library, and wishing to keep my development work separate from the stable wxHaskell from hackage I'm using cabal-dev in the following manner:
I obtained the source for wxHaskell from darcs;
Because wxHaskell is comprised of three components I used cabal-dev add-source to add each one (wx, wxcore, wxdirect);
I was then able to install into a sandbox local package library by doing cabal-dev install wx, as expected, the dependencies were detected and everything built and installed.
Finally I successfully ran my test code by using ghc -package-conf to specify the location of the sandboxed package database.
The problem comes when I make modifications to the wxHaskell source. In order to build and install the updated code I have to use cabal-dev install --reinstall, which makes sense as I don't increment the version number; the build takes place and I see "Installing library in..." and "Registering..." but the changes I've made in the code aren't present in the recompiled sandbox library.
The work around I have at the moment is to delete the cabal-dev library and repeat the process every time I want to rebuild.
UPDATE: cabal-install >= 1.18 has support for sandboxes, and will be better maintained than cabal-dev going forward. Cabal-install also has better support for using add-source with sandboxes. Here's a description of the new sandboxing features in cabal-install: http://coldwa.st/e/blog/2013-07-30-Cabal-sandbox.html
Old answer:
As you found, 'add-source' is not meant for use with actively changing projects. I'm not sure that there is a good solution there either - it's difficult to track the location of an add-source'd project (there is no existing infrastructure for that, at least), and I'm not sure that's always the right thing.
Another workflow may serve you better - just use cabal-dev install, pointing to the sandbox you wish to use for future development. Recent versions of the cabal toolchain (by which I mean Cabal, cabal-install and cabal-dev) allow for this sort of thing:
$ ls
wx wxcore wxdirect
$ cabal-dev install --sandbox=<path-to-some-sandbox> ./wx ./wxcore ./wxdirect
...
(Note: I have not tested this with WX - kinks may arise that I'm unaware of!)
Assuming everything goes as expected, that will install the three packages from the local sub directories into the specified sandbox. Updating the source just means re-issuing a cabal-dev install command for the project that changed.
Keep in mind that you must either issue the repeated cabal-dev install commands in the correct order on your own, or you must use the batch command above and update version numbers accordingly.
I make no claims about this being ideal ;) but I think it's better than deleting the sandbox each time.
After some investigation I can confirm that this is a result of my misunderstanding regarding the usage of add-source, as detailed in "Using a sandbox-local Hackage" section of the README, which is given here (the strong was added by myself and indicates the reason for my misunderstanding):
Cabal-dev also allows you to use un-released packages as though they
were on hackage with cabal-dev add-source.
For example, the linux-ptrace and posix-waitpid packages were only
recently uploaded to hackage. Previously, cabal-dev was used to build
applications that depended on these two packages:
$ ls
linux-ptrace/ myProject/ posix-waitpid/
$ cd myProject
$ cabal-dev add-source ../linux-ptrace ../posix-waitpid
$ cabal-dev install
Note that cabal-dev add-source accepts a list of source locations.
Be careful, however, because packages that have been added are not
tied to their original source locations any more. Changes to the
linux-ptrace source in the above example will not be used by
myProject unless the user issues cabal-dev add-source with the
path to the linux-ptrace source again. This is similar to the
cabal install step you may do now to enable a project to make use of
changes to a dependency.

Resources