1. Getting Started with Haskell and Cabal

1.1. Installing the Haskell toolchain

To install the Haskell toolchain follow the ghcup instructions if you’re using Linux or Mac, or follow this guide if you’re using Windows.

1.2. Creating a new application

Let’s start by creating a simple Haskell application from scratch where we’ll learn about a Haskell package’s directory structure, how to run the executable, and how to add external dependencies.

1.2.1. Initializing the application

Start by creating a myfirstapp directory to hold the project files, these instructions work in unix shells and PowerShell (if you’re on Windows).

$ mkdir myfirstapp
$ cd myfirstapp

Once you have an empty directory we can initialize our package:

$ cabal init --cabal-version=2.4 --license=NONE -p myfirstapp


cabal-version refers to the version of the .cabal file format specification, that can be different from the versions of the cabal library and tool in use. It is common to use a slightly older cabal-version, to strike a compromise between feature availability and backward compatibility.

This will generate the following files:

$ ls

Main.hs is where your package’s code lives. By default cabal init creates an executable with the same name as the package myfirstapp in this case, you can instruct cabal init to generate just a library (with --lib) or both a library and executable with (--libandexe); for the full set of options see cabal init --help.

myfirstapp.cabal is Cabal’s metadata file which describes your package and its dependencies. We’ll be updating this file in a little bit when we add an external dependency to our package.

1.2.2. Running the application

As mentioned above, cabal init with no arguments generates a package with a single executable that prints "Hello, Haskell!" to the terminal. To run the executable enter the following command:

cabal run :myfirstapp

You should see the following output in the terminal:

$ cabal run :myfirstapp
Hello, Haskell!


The : prefix in :myfirstapp signifies that the myfirstapp target is part of the current package.

Notice that we didn’t need to run a build command before cabal run, this is because cabal run first determines if the code needs to be re-built before running the executable. If you just want to build a target you can do so with cabal build:

cabal build :myfirstapp

1.2.3. Adding dependencies

Next we’ll add an external dependency to our application. Hackage is the Haskell community’s central package archive of open source software.

In our application, we’ll use a package called haskell-say to print text to the terminal with some embellishment.


If you installed cabal a while ago but haven’t used it recently you may need to update the package index, you can do this by running cabal update.

In our myfirstapp.cabal file we’ll update the build-depends attribute of the executable myfirstapp section to include haskell-say:

executable myfirstapp
    main-is: Main.hs
        base >=4.11 && <4.12,
        haskell-say ^>=


^>= means use version of the library or any more recent minor release with the same major version.

Next we’ll update Main.hs to use the HaskellSay library:

module Main where

import HaskellSay (haskellSay)

main :: IO ()
main =
  haskellSay "Hello, Haskell! You're using a function from another package!"

import HaskellSay (haskellSay) brings the haskellSay function from the module named HaskellSay into scope. The HaskellSay module is defined in the haskell-say packages that we added a dependency on above.

Now you can build and re-run your code to see the new output:

$ cabal run
   /                                                        \
  | Hello, Haskell! You're using a function from another     |
  | package!                                                 |
   \____       _____________________________________________/
        \    /
         \  /
    _____   _____
    \    \  \    \
     \    \  \    \
      \    \  \    \
       \    \  \    \  \-----------|
        \    \  \    \  \          |
         \    \  \    \  \---------|
         /    /  /     \
        /    /  /       \  \-------|
       /    /  /    ^    \  \      |
      /    /  /    / \    \  \ ----|
     /    /  /    /   \    \
    /____/  /____/     \____\

1.3. What Next?

Now that you know how to set up a simple Haskell package using Cabal, check out some of the resources on the Haskell website’s documentation page or read more about packages and Cabal on the introduction page.