# 1. Getting Started

## 1.1. Installing Cabal

The easiest and recommended way to install the `cabal` command-line tool on Linux, macOS, FreeBSD or Windows is through ghcup. It installs the “Haskell toolchain”, which includes Cabal, the Haskell compiler GHC and optionally other useful Haskell tools.

## 1.2. Creating a new application

We create a minimal Haskell application to get a quick overview of the `cabal` command-line tool:

1. How to initialize a Haskell package.

2. How files are organized inside a package.

3. How to compile Haskell files and run a resulting executable.

4. How to manage external dependencies.

### 1.2.1. Initializing an application

To initialize a new Haskell application, run

    $ cabal init myapp --non-interactive

in a terminal. This generates the following files in a new `myapp` directory:

    $ tree
    .
    └── myapp
        ├── app
        │   └── Main.hs
        ├── CHANGELOG.md
        └── myapp.cabal

The `myapp.cabal` file is a package description file, commonly referred to as a “Cabal file”:

    cabal-version:      3.0
    name:               myapp
    version:            0.1.0.0
    -- ...

    executable myapp
        import:           warnings
        main-is:          Main.hs
        build-depends:    base ^>=4.19.0.0
        hs-source-dirs:   app
        default-language: Haskell2010

Warning

The version bounds on base, a boot library distributed with GHC [1], are tied to the GHC version visible when `cabal init` is run. If run with a later version of GHC you might see a difference in the version bounds.

    - build-depends:    base ^>=4.19.0.0
    + build-depends:    base ^>=4.20.0.0

It contains metadata (package name and version, author name, license, etc.) and sections to define package components. Components can be used to split large codebases into smaller, more manageable building blocks. A component can be of one of several types (executable, library, etc.) and describes, among other things, the location of source files and its dependencies. The `myapp.cabal` file above defines a single component named `myapp` of the executable type. Inside the `executable` section, the `build-depends` field lists the dependencies of this component.

The `app/Main.hs` file is where your executable’s code lives:

    module Main where

    main :: IO ()
    main = putStrLn "Hello, Haskell!"

To run the executable, switch into the application directory with `cd myapp` and run

    $ cabal run myapp
    ...
    Hello, Haskell!

This command automatically determines if the executable needs to be (re)built before running the executable. With only one executable component in the package, `cabal run` (without a component name) is smart enough to infer it, so the name can be omitted.

If you just want to build the executable without running it, run:

    $ cabal build
    Resolving dependencies...
    ...
    Building executable 'myapp' for myapp-0.1.0.0..
    [1 of 1] Compiling Main             ( app/Main.hs, /home/.../myapp/dist-newstyle/build/.../myapp-tmp/Main.o )
    Linking /home/.../myapp/dist-newstyle/build/.../myapp

### 1.2.2. 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.

Tip

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 `myapp.cabal` file, we will update the `build-depends` field of the executable section to include `haskell-say`:

    executable myapp
        import: warnings
        main-is: Main.hs
        build-depends:
            base ^>=4.19.0.0,
            haskell-say ^>=1.0.0.0
        hs-source-dirs: app
        default-language: Haskell2010

Note

`^>=1.0.0.0` means use version 1.0.0.0 of the library or any more recent minor release with the same major version. To put it simply, this means use the latest version of the library that starts with `1.0`.

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

    module Main where

    import HaskellSay (haskellSay)

    main :: IO ()
    main = haskellSay "Hello, Haskell!"

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

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

    $ cabal run myapp
        ________________________________________________________
       /                                                        \
      | Hello, Haskell!                                          |
       \____       _____________________________________________/
            \    /
             \  /
              \/
        _____   _____
        \    \  \    \
         \    \  \    \
          \    \  \    \
           \    \  \    \  \-----------|
            \    \  \    \  \          |
             \    \  \    \  \---------|
             /    /  /     \
            /    /  /       \  \-------|
           /    /  /    ^    \  \      |
          /    /  /    / \    \  \ ----|
         /    /  /    /   \    \
        /____/  /____/     \____\

## 1.3. Running a single-file Haskell script

Cabal also supports running single-file Haskell scripts like the following file named `myscript`:

    #!/usr/bin/env cabal
    {- cabal:
    build-depends:
      base,
      haskell-say ^>=1.0.0.0
    -}

    import HaskellSay (haskellSay)

    main :: IO ()
    main = haskellSay "Hello, Haskell!"

Note

Widening or dropping version bound constraints on packages included with the compiler [1], like `base`, may allow single-file scripts to run with a wider range of compiler versions.

    build-depends:
    -   base ^>=4.19.0.0,
    +   base,

The necessary sections of a `.cabal` file are placed directly into the script as a comment.

The necessary sections of a package description that would otherwise be in a `.cabal` file are placed directly into the script as a comment.

Use the familiar `cabal run` command to execute this script:

    $ cabal run myscript

On Unix-like systems, a Haskell script starting with `#!/usr/bin/env cabal`, like the one above, can be run directly after setting the execute permission (+x):

    $ chmod +x myscript
    $ ./myscript
       ________________________________________________________
      /                                                        \
     | Hello, Haskell!                                          |
      \____        ____________________________________________/
           \ ... /

See more in the documentation for cabal run.

Warning

Single-file scripts cannot also be part of a package, as an executable or listed as a module. Trying to run a module that is included in a package will error with Cabal-7070.

## 1.4. 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 What Cabal does page.

[1] (1,2)

Packages included with the compiler are also called boot packages. Each GHC compiler version has accompanying release notes that list these included packages.