text: The Cabal of CabalAlbert Y. C. Lai, trebla [at] vex [dot] net
  ca·bal noun: the artifices and intrigues of a group of persons secretly united in a plot
  The undocumented or obscure artifices and intrigues of Cabal. And these are just some important and useful ones!
  User Guide
  Cabal has a user guide! Did you know? Link
  However, it still doesn't tell you everything…
  Wrong Defaults
  .cabal/config defaults want you to never write in Haskell! Or never read docs and never profile. Look at these lines:
  -- library-profiling: False ... -- documentation: False
  This is an expensive error. One day, you will want library documentation on your own hard disk. One day, you will need profiling. When the day comes, you will have to distract yourself and reinstall a lot of packages. Reinstalling is slow or unsafe: pick one.
  To correct this error, uncomment and change the lines:
  library-profiling: True ... documentation: True
  (This paragraph assumes that you have hscolour.) Even this does not enable
  hyperlinking from docs to coloured source code. There is no config line for it.
  You must manually type
  cabal install --haddock-hyperlink-source
  every time, every bloody time.
  OK, you have now adjusted your config, and ready to bite the bullet and reinstall. Here is the slow, safe, scorched earth policy. Do not succumb to the sunk cost fallacy.
  Understand my removing packages. In fact, understand the whole thing.
  We will be erasing all user packages. Slow, safe, scorched earth policy. Do not succumb to the sunk cost fallacy.
  Therefore, before erasing, do jot down which packages not already from GHC and Haskell Platform (if you have it) that you will want back after erasing.
  Do not jot down packages from GHC and Haskell Platform installers—they already come with docs, profiling, dynamic linking, everything. Only cabal-install disables everything, like it hates Haskell programmers.
  Erase: erase the appropriate metadata directory $HOME/.ghc/arch-ghcversion
  Install back: Use
  cabal installto install back the packages you jotted down. Do not use multiple commands. Use one single command for the whole roster, so that cabal-install can compute one single coherent set. Example:
  cabal install --haddock-hyperlink-source lens netwire hxt hxt-http
  (If you don't have hscolour,
  --haddock-hyperlink-sourcedoes not apply.)
  Lock Down Library Versions
  Co-existing multiple versions or instances of a library is problematic, see my the pigeon-drop con. There is no such thing as “upgrade”; there is only reinstall and install more.
  To guard against multiple versions or instances of bytestring and containers
  (say) during
  cabal install, add these flags:
  --constraint "bytestring installed" --constraint "containers installed"
  or insert these lines into $HOME/.cabal/config:
  constraint: bytestring installed constraint: containers installed
  A complete list for Haskell Platform is at my Haskell Platform article.
  Moar Optimization
  .cabal/config defaults optimization to
  -- optimization: True
  This means passing -O to GHC. Do you want -O2 instead? Without command line options? You can change the config line to:
  optimization: 2
  That's right, it does not have to be boolean! The complete list of valid values are: False, false (will cause warning), 0, True, true (will cause warning), 1, 2.
  Haskell 2010
  Cabal normally tells GHC to use Haskell 98. This is why some files are accepted when using GHC by hand but rejected when using Cabal. To correct this error: In project.cabal files, under each library section and executable section, add this undocumented field
  default-language: Haskell2010
  As a result of using this setting, it is also a good idea to request Cabal version 1.10 or higher in the global (top) section:
  cabal-version: >=1.10
  So here is how it goes in a sample project.cabal file:
  name: dummy version: 1.1 cabal-version: >= 1.10 build-type: Simple author: Albert Y. C. Lai category: Dummy synopsis: Example executable and example library. executable dummy main-is: dummy.hs build-depends: base >= 4 default-language: Haskell2010 library exposed-modules: Dummy build-depends: base >= 4 default-language: Haskell2010
  Its significance is exemplified by the following file, which uses Haskell 2010 new features left right and centre. As said, it is normally accepted by GHC, but normally rejected via Cabal, unless you add the above line.
  import Data.Set(empty, minView) -- foreign declarations foreign import ccall abort :: IO () -- pattern guards f s | Just (x, s1) <- minView s = x | Nothing <- minView s = "empty" -- do and if-then-else main = do if False then abort else putStrLn (f empty)
  And just what more undocumented valid fields can you use in project.cabal files? This brings us to…
  project.cabal Fields
  To find out more undocumented valid fields in project.cabal, deliberately
  add an invalid field (and value) under the desired section, then run
  cabal configure.
  Compound Constraints
  Version constraints can mix
  && (higher precedence) and
  || (lower precedence), and also use parentheses to override
  precedences. Example:
  base ==10.* || <9 && (<3 || >4) || ==12.*
  Local Repository
  You can host additional package repositories on your file system! And yes that's plural, you can have more than one.
  Let's say one repository is at /home/trebla/must-have, and it has these packages: doggie 1.0, kitteh 1.1, kitteh 1.2. Here is the expected file system layout in /home/trebla/must-have:
  doggie/1.0/doggie-1.0.tar.gz
  kitteh/1.1/kitteh-1.1.tar.gz
  kitteh/1.2/kitteh-1.2.tar.gz
  00-index.tar, which tars up  file system layout is different from remote repositories described next, and it is not just because 00-index.tar is uncompressed here. Don't you love gratuitous inconsistencies?
  And here is the line in .cabal/config to use that repository:
  local-repo: /home/trebla/must-have
  You can use many local repositories. Just add more
  local-repo
  lines.
  cabal-install will add the file 00-index.cache to the repositories for its own use. You do not have to worry about maintaining it. Just keep your 00-index.tar up to date, and cabal-install will do the right thing.
  You do not need to run
  cabal update for changes in local
  repositories.
  Remote Repository
  You can also host and/or use additional remote package repositories! And yes that's also plural, you can have more than one.
  Let's say one repository is at, and it has these packages: doggie 1.0, kitteh 1.1, kitteh 1.2. Here are the expected relative paths of files:
  package/doggie-1.0.tar.gz
  package/kitteh-1.1.tar.gz
  package/kitteh-1.2.tar.gz
  00-index.tar.gz, which tars up and compresses  layout is different from local repositories described previously, and it is not just because 00-index.tar.gz is compressed here. Furthermore it is different from Hackage: cabal-install has special code to detect the URL “hackage.haskell.org/packages/archive” and compute paths differently. Don't you love gratuitous inconsistencies?
  And here is the line in .cabal/config to use that repository. First you have to choose a name; it is up to you and it just has to be unique. Let's say you choose “catdog”. Then the line is:
  remote-repo: catdog:
  You can use many remote repositories. Just add more
  remote-repo
  lines and give them names. (In fact, you already have one for Hackage.) And they
  don't have to be http://, they can also be file://.
  You need to run
  cabal update for remote repositories. This
  downloads and caches 00-index.tar.gz. Explore .cabal/packages to see what is
  cached there.
  cabal install ≠ Setup install
  Many people use this idiom in a source tree to build and install:
  cabal configure cabal build cabal install
  This idiom is an urban legend, i.e., a popular error. The 3rd step
  cabal install re-does the 1st and 2nd steps, among other
  things. Redundant work looks harmless so far, until one day you need
  non-default options:
  cabal configure --prefix=/nondefault --flags=debug cabal build cabal install
  Whee! Your laborously entered options are lost on deaf ears. The 3rd
  step
  cabal install without options re-does
  cabal
  configure without options. Your options are erased.
  The correct idiom is:
  cabal configure --prefix=/nondefault --flags=debug cabal build [cabal haddock [--hyperlink-source]] cabal copy cabal register
  or simply
  cabal install --prefix=/nondefault --flags=debug [--enable-documentation [--haddock-hyperlink-source]]
  This concludes the practical advice. But the story doesn't end here.
  The urban legend probably arises from this analogy:
  And you would think that it would carry over to
  cabal, no?
  No:
  Setup installdoes not repeat
  Setup configureor
  Setup build
  Setupdefaults to
  --global,
  cabaldefaults to
  --user(see my SICP)
  Don't you love gratuitous inconsistencies?
  So why did they choose the name
  cabal install for the all-in-one
  command? Probably because of another analogy:
  The
  cabal program tries too hard to use the Makefile analogy and
  the Debian analogy together. Analogies are like drugs.
  I have more Haskell Notes and Examples