Dependencies

Contents
Add a dependency
Update the index
Version bounds
Freeze and lock

Add a dependency

Hackage hosts the packages. Adding one means one line in build-depends, and Cabal resolves the rest:

build-depends: base >=4.18 && <5 , text >=2.0 && <3 , containers >=0.6 && <0.8 , aeson >=2.2 && <3

text gives packed strings, containers gives maps and sets, and aeson reads and writes JSON. Those four plus base cover most command line tools.

Update the index

Cabal keeps a local copy of the package index. When a version you need is missing, refresh it:

cabal update

Downloading the latest package list from hackage.haskell.org Package list of hackage.haskell.org is up to date.

Then build. The solver prints the plan it chose, and the first build compiles the dependencies, which can take several minutes:

cabal build

Resolving dependencies... Build profile: -w ghc-9.10.1 -O1 In order, the following will be built: - text-2.1.1 (lib) - todo-0.1.0.0 (exe:todo)

Version bounds

A bound says which versions your code was tested with. Too tight and the project blocks every update; too loose and a breaking release compiles by accident:

-- reasonable: one major version window text >=2.0 && <3 -- too loose: any version, including the next rewrite text

The convention is a lower bound on the version you actually used and an exclusive upper bound on the next major release. The cabal check command flags missing bounds before you upload a package.

Freeze and lock

A build that worked today should work next year. Freezing records the exact versions in a plan file, and a project file pins the compiler and index state:

cabal freeze

Wrote freeze file: /home/ada/todo/cabal.project.freeze

Commit cabal.project.freeze for an application and leave it out for a library. Applications want reproducible builds, libraries want to be testable against new dependency versions.

Next: Testing with HUnit

Article author: Arthur Isaev

Related articles
Haskell
Haskell course: zero to hero in 50 lessons
What is Haskell and why it matters
Install the toolchain with GHCup
GHCi: the interactive shell
Your first program
Values with let and where
Types and type signatures
Functions and application
Currying and partial application
Operators, sections, and fixity
if, guards, and pattern guards
case expressions
Pattern matching
Tuples
Lists
Ranges and enumeration
List comprehensions
Recursion replaces loops
map, filter, and foldr
Lambdas and composition
Type classes
Parametric polymorphism
Maybe and null safety
Either and recoverable errors
data: product types
data: sum types
Records
newtype and type synonyms
Recursive data: binary trees
Functor
Applicative
Monad
do notation
IO and purity
Files and IO
Modules and imports
Cabal projects
Dependencies
Testing with HUnit
Property testing with QuickCheck
Laziness and infinite lists
Strictness and space leaks
Folds
Monoids
Traversable
Monad transformers
Errors and exceptions
Concurrency
Parsing with Megaparsec
Capstone: a todo CLI
Hero roadmap: the whole course on one page
Banner image

Search this site

Channel @aofeed Chat @aofeedchat

Contacts and cooperation:
I recommend our hosting beget.com
Write to info@aredel.com if you:
1. Want to write an article for our site or translate an article into your native language.
2. Want to place thematically relevant ads on the site.
3. Ads on my site pass maximum censorship. If you see an ad block unsuitable for school-age children, shocking or misleading - please contact us by e-mail
4. Found a mistake, inaccuracy, bug, etc. on the site. ... .......
5. Articles can be shared on social media by clicking a network icon: