# Stack, Cabal etc

[Stack](https://docs.haskellstack.org/en/stable/README/) is *a* (not the only) Haskell standard for scaffolding, building, packaging and managing dependencies for a project. It uses [Cabal](https://www.haskell.org/cabal/) under the covers. The interplay between Stack, Cabal and [HPack](https://github.com/sol/hpack) makes this area a bit of a minefield.

## Start a new stack project

In parent directory, where `simple` is the template from `stack templates` list:

```bash
stack new [project-name] simple
```

## Run ghci

GHCi session in the context of the current project:

```bash
stack ghci
```

## Build and run executable

```bash
stack build && stack exec package-name-exe
```

## Install a dependency

* For a global package install, (like `npm install -g package`) use cabal NOT stack:

```bash
cabal update && cabal install package
```

* For a local package install restricted to only a stack project (like `npm install --save package`):

```
    dependencies:
    - haskell-hspec
    - hspec
    - QuickCheck
```

* This will in turn generate an edit to the project's Cabal file `project.cabal`:

```
  build-depends:       base
                     , haskell-hspec
                     , hspec
                     , QuickCheck
```

## List depedencies

```bash
stack list-dependencies
```

## Pass and argument to stack ghc

```bash
stack ghc -- --supported-extensions
```

## Environment setup

### What is my global ghc, why, and how do I change it?

Global ghc could have been installed in all sorts of ways, it is found by running:

```bash
ghc -v
```

But really you probably want to be using a Stack managed global setup e.g. outside of a project folder, run one of the following commands:

```bash
stack ghci -v
stack ghc -v
```

This should tell you in the logs that you are using e.g. `.stack/global-project/stack.yaml`. The `resolver` field in this file will determine which ghc version you are using.

### What is my project GHC, why, and where is it stored?

The project ghc is set via the local `stack.yaml`, again using the resolver to determine the version. ghc itself will be installed somewhere centrally by Stack.

### What are my globally installed packages, why, and where are they stored?

The following command when run globally tells you all of the packages which are installed:

```bash
ghc-pkg list
```

### What are my project installed packages, why, and where are they stored?

```bash
stack list-dependencies
```

### Where does stack build my executables?

```bash
stack path --local-install-root
```

## Useful resources

* [Problems with Cabal and how to avoid](https://wiki.haskell.org/Cabal/Survival)
* [Cabal github repo](https://github.com/haskell/cabal)
* [Why is Stack not Cabal](https://www.fpcomplete.com/blog/2015/06/why-is-stack-not-cabal)
* [Stackage is Stable Hackage and packages here have been tested to avoid dependency conflicts](https://www.stackage.org/)
* [Stack.yaml versus .Cabal](https://docs.haskellstack.org/en/stable/stack_yaml_vs_cabal_package_file/)
* [Stack FAQs](https://github.com/commercialhaskell/stack/blob/master/doc/faq.md)

## Notes

The logic for resolving dependencies without and with Stack is as follows:

* Packages GHC can use > Are registered with "ghc-pkg register" > And (almost always) built with Cabal > With build dependencies resolved by cabal-install > From Hackage.
* Packages GHC can use > Are registered with "ghc-pkg register" > And (almost always) built with Cabal > With build dependencies resolved by stack > From Stackage (if possible...) or Hackage

Stackage specifies a 'resolver'

> a GHC version, a number of packages available for installation, and various settings like build flags"

[Global Stack managed dependencies](https://docs.haskellstack.org/en/stable/yaml_configuration/):

* `/etc/stack/config.yaml` - for system global non-project default options
* `~/.stack/config.yaml` - for user non-project default options

When stack is invoked outside a stack project it will source project specific options from `~/.stack/global-project/stack.yaml`. When stack is invoked inside a stack project, only options from `<project dir>/stack.yaml` are used, and `~/.stack/global-project/stack.yaml` is ignored.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://wiki.robmurtagh.com/haskell/stack-cabal-etc.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
