EDIT - Much confusion on my part as the Cabal versioning policy's (PVP) tracks the major version as A.B while Semantic Versioning's major version is only X. The second point confusion was the Semantic Versioning having a distinguished major version zero (0.y.z) which by convention implies instability.
So I was reading the latest about Cabal Hell and thinking about how it just doesn't happen to me anymore as I pretty much follow much of the points outlined in the latest how to avoid Cabal Hell discussion.
And then this morning ... fire and brimstone
The conflict happened as a result of two sets of narrow cabal bounds for attoparsec in two different libriaries.
For the remainder of my thoughts, I'm assuming the principles of Semantic Versioning apply.
To cut to the chase either there is a true conflict or there is not. If not, the bounds can be adjusted in one or both libraries creating an overlapping range or they safely cannot.
At the moment I don't as of yet know which situation applies.
However, all too often it's the latter, a false positive conflict from the overally conservative narrow version bounds. However, I'd do the same myself, i.e. be very conservative in using a narrow attoparsec version bounds as Attoparsec is specific in stating that it is a) Experimental and b) unstable (Semantic Versioning 0.x.y.z versions)
So for the sake of discussion point, and only so, I'll specifically use attoparsec here a bit. Attoparsec was first published 6 years ago with 40+ version releases and is one of the most widely used libs out there as a dependency. Why is the only use option for attoparsec one of experimental / unstable with only 0.x.y.z versions? In other words, why couldn't as least one V1.x have been tied off?
Consider the following situations for a Haskell library developer thinking of using attoparsec this morning:
1) attoparsec as-is is experimental and a 0.x.y.z versioned library subject to at will API modification. => If I use it, I'm going to put a really narrow cabal bounds band on this thing.
2) attoaparsec could-be has a V1.x, V2.x, ... set of releases. Each major release series stable in the sense of a fixed set of functionality and corresponding api + semantics. I can safely set my cabal range on a specific Major.Minor version. IF some user sees a conflict in Major.Minor version down the road, the probability is pretty high that yep, we have a real conflict here and not a case of a pessimistic narrow bounds false positive conflict.
Of course every library has a Experimental phase before solidifying into a minimal viable V1.x library and evolving in a backwards incompatable manner via V2.x ... . However attoparsec has been out there for 6 years, over 40 versions and is wildly successful. Hackage life would be far easier if attoparsec had foundone or more points of library stability along the way.
Once more I'm simply using attoparsec as an example here and not picking on it per se. The main idea here is that if essential, widely used libraries declare themselves experimental and unstable for perpetuity people are going to react by applying very narrow bounds constraints resulting in too frequent false positive conflicts.submitted by precium
[link] [28 comments]
With that preface, here are my best practices that seem to make Cabal work pretty well for me in my development.
1. I make sure that I have no more than the absolute minimum number of packages installed as --global. This means that I don't use the Haskell Platform or any OS haskell packages. I install GHC directly. Some might think this casts too much of a negative light on the Haskell Platform. But everyone will agree that having multiple versions of a package installed at the same time is a significant cause of build problems. And that is exactly what the Haskell Platform does for you--it installs specific versions of packages. If you use Haskell heavily enough, you will invariably encounter a situation where you want to use a different version of a package than the one the Haskell Platform gives you.
2. Make sure ~/.cabal/bin is at the front of your path. Hopefully you already knew this, but I see this problem a lot, so it's worth mentioning for completeness.
3. Install happy and alex manually. These two packages generate binary executables that you need to have in ~/.cabal/bin. They don't get picked up automatically because they are executables and not package dependencies.
4. Make sure you have the most recent version of cabal-install. There is a lot of work going on to improve these tools. The latest version is significantly better than it used to be, so you should definitely be using it.
5. Become friends with "rm -fr ~/.ghc". This command cleans out your --user repository, which is where you should install packages if you're not using a sandbox. It sounds bad, but right now this is simply a fact of life. The Haskell ecosystem is moving so fast that packages you install today will be out of date in a few months if not weeks or days. We don't have purely functional nix-style package management yet, so removing the old ones is the pragmatic approach. Note that sandboxes accomplish effectively the same thing for you. Creating a new sandbox is the same as "rm -fr ~/.ghc" and then installing to --user, but has the benefit of not deleting everything else you had in --user.
6. If you're not working on a single project with one harmonious dependency tree, then use sandboxes for separate projects or one-off package compiles.
7. Learn to use --allow-newer. Again, things move fast in Haskell land. If a package gives you dependency errors, then try --allow-newer and see if the package will just work with newer versions of dependencies.
8. Don't be afraid to dive into other people's packages. "cabal unpack" makes it trivial to download the code for any package. From there it's often trivial to make manual changes to version bounds or even small code changes. If you make local changes to a package, then you can either install it to --user so other packages use it, or you can do "cabal sandbox add-source /path/to/project" to ensure that your other projects use the locally modified version. If you've made code changes, then help out the community by sending a pull request to the package maintainer. Edit: bergmark mentions that unpack is now "cabal get" and "cabal get -s" lets you clone the project's source repository.
9. If you can't make any progress from the build messages cabal gives you, then try building with -v3. I have encountered situations where cabal's normal dependency errors are not helpful. Using -v3 usually gives me a much better picture of what's going on and I can usually figure out the root of the problem pretty quickly.
How would you create a Haskell program that stores mutable Haskell expressions? (Kinda complicated explanation.)
I am trying to create a Haskell program that stores Haskell expressions and their reductions. I must admit that after reading a lot about Haskell, monads, and thinking a lot about the problem, I still have no idea where even to start this. So, let me show an example of what I want:a <- 1 b <- 2 c <- 3 d <- 4 e <- [a,b,c,d] f <- (\l -> case l of  -> 0; (x:xs) -> x + s xs) g <- f e print e -- output: [1,2,3,4] print g -- output: 10 a <- 11 print e -- output: [11,2,3,4] print g -- output: 20 h <- 5 e <- [a,b,c,d,h] print e -- output: [11,2,3,4,5] print g -- output: 25 f <- (\l -> case l of  -> 0; (x:xs) -> x * 2 + s xs) print e -- output: [11,2,3,4,5] print g -- output: 50
This is not in any particular language, but do you get what I've done? To put it on words, I want a way to store a database of Haskell terms and their reductions. There are 2 problems, though:
You can modify a term and, when you do, all terms that use this term will get updated.
Terms are cons-hashed and reductions are memoized by term. So, a <- [1,2] and b <- [1,2], a and b are equal by reference and the reduction is cached.
Is the problem as complicated as I am starting to believe it is? I need some help for the overall design of this. How would you guys do it? What are the libraries that could help?submitted by Padavo
[link] [15 comments]
I am having no trouble at all in getting Haskell basics. Function, currying, purity, laziness, monads somewhat. All have a lot of great resource options. But just having finished the LYAH book, I have no idea where to go now. I see you guys talking about advanced things all the time - GADTs, Lenses, REPA, monad transformers. I see a lot of cool libraries with no explanations or tutorials. There doesn't seems to be many Haskell books. It is becoming harder and harder to get further down the rabbit hole.
So, considering that lack of resources and courses for advanced stuff, it would be really great if you compiled a list of the available Haskell resources. Books, tutorials, blog posts. One complete enough to contain everything someone should read to go from complete novice to mastery by himself.submitted by Padavo
[link] [72 comments]
I've been using Haskell quite heavily in the past few months, and I just keep experiencing cabal hell over and over again. Here's basically my list of questions. Most recently when I tried to install darcs I'm not even able to build it in a sandbox. I always thought that cabal unpack darcs; cd darcs; cabal sandbox init; cabal install should always pass, but it doesnt, so I guess I must be doing something wrong?
This is probably my biggest question, how can I compile something which fails to install it's dependencies even when using a sandbox? Here are a few more questions:
- How should I install binaries like yesod-bin, darcs, ghc-mod, hlint, etc., where I'd like to have them available globally? (Should I just cabal unpack, build in a sandbox and copy the binary somewhere safe?)
- How should I install packages which I do want globally, such as lens? The reason for this is that when playing around with things I don't want to keep reinstalling sandboxes over and over again, what's the best practice here? Should I install all of the things I use in one big cabal install?
- When and for what should I be using Stackage? Is it better to just wipe everything from ~/.cabal and ~/.ghc, add stackage and start installing things from scratch? How much does this help when using the inclusive build compared to regular hackage?
- What should I do when I stuble upon a package which I need to build, but it results in dependency issues like this. Is there a way to fix that, other than ghc-pkg unregistering all the packages which it conflicts with?
- If I use the pre-built binaries for ghc and install everything myself, is that safer than using haskell-platform? I've found that when using the haskell-platform I have to ghc-pkg unregister quite a lot of things to get some things compiled.
If you guys have any other tips for avoiding or figuring out the cabal hell, or techniques you use to manage dependencies, or just anything related to working with cabal properly, please do post them in the comments.
The only way I've been fixing this stuff is just brute force deleting packages or completely re-installing everything, which doesn't seem right.submitted by progfu
[link] [30 comments]
import Prelude hiding (filter)
import qualified Data.Map as Map
import Data.Map (Map)
-- | A 'Set' as a 'Map' to '()'.
newtype Set a = Set (Map a ()) deriving (Eq,Ord,Show)
-- | An empty 'Set'.
empty :: Set a
empty = Set ()
-- | Insert and element into a 'Set'.
insert :: (Ord a) => a -> Set a -> Set a
-- | Test if an element is in a 'Set'.
member :: (Ord a) => a -> Set a -> Bool
member _ empty = False
-- | Filter all members that satisfy a predicate.
filter :: (a -> Bool) -> Set a -> Set a
filter _ empty = empty
Cany anyone help me with the rest of this questions. I didn't really know how to understand this.. Thanks.submitted by fuuman1
[link] [9 comments]
Does this make sense? If I coded the right monad, could this be valid Haskell code? How would that monad look like?
Someone pointed me the State monad, but I still don't get it.submitted by Padavo
[link] [11 comments]
cabal-bounds is a command line program for managing the bounds/versions of the dependencies in a cabal file.
cabal-bounds 0.7 adds the feature to set the bounds of dependencies to the library versions used by a haskell platform release.
For further details please consult the README.dan00
[link] [17 comments]