Produce a cabal.project file upon `cabal init` to pin the GHC version explicitly
- Dominant language
- Haskell
- Stars
- 1.7k
- Forks
- 750
- Avg merge
- 4d 3h
- Merged PRs (30d)
- 28
Description
## Context
After spending some time in the contact of beginners, a recurring thing has been noted: The GHC version is indirectly constrained by the bounds on the `base` library.
This is not a very common behaviour in other ecosystems, and each time I explain how this works, I feel like I am just describing a very weird and counter-intuitive situation instead of giving an actual good reason.
From a personal standpoint I also systematically write down:
```cabal
packages: ./
with-compiler: ghc-9.8
```
in my new executable projects.
### Compare the difference in user experience:
#### When exclusively relying on base bounds
```
Error: [Cabal-7107]
Could not resolve dependencies:
[__0] trying: myproject-0.1.0.0 (user goal)
[__1] next goal: base (dependency of myproject)
[__1] rejecting: base-4.18.2.1/installed-4.18.2.1 (conflict: myproject => base^>=4.19)
[__1] skipping: base; 4.20.0.1, 4.20.0.0 (has the same characteristics that caused the previous version to fail: excluded by constraint '^>=4.19' from 'myproject')
[__1] rejecting: base; 4.19.1.0, 4.19.0.0, 4.18.2.1, 4.18.2.0, 4.18.1.0, 4.18.0.0, 4.17.2.1, 4.17.2.0, 4.17.1.0, 4.17.0.0, 4.16.4.0, 4.16.3.0, 4.16.2.0, 4.16.1.0, 4.16.0.0, 4.15.1.0, 4.15.0.0, 4.14.3.0, 4.14.2.0, 4.14.1.0, 4.14.0.0, 4.13.0.0, 4.12.0.0, 4.11.1.0, 4.11.0.0, 4.10.1.0, 4.10.0.0, 4.9.1.0, 4.9.0.0, 4.8.2.0, 4.8.1.0, 4.8.0.0, 4.7.0.2, 4.7.0.1, 4.7.0.0, 4.6.0.1, 4.6.0.0, 4.5.1.0, 4.5.0.0, 4.4.1.0, 4.4.0.0, 4.3.1.0, 4.3.0.0, 4.2.0.2, 4.2.0.1, 4.2.0.0, 4.1.0.0, 4.0.0.0, 3.0.3.2, 3.0.3.1 (constraint from non-reinstallable package requires installed instance)
[__1] fail (backjumping, conflict set: base, myproject)
After searching the rest of the dependency tree exhaustively, these were the goals I've had most trouble fulfilling: base, myproject
```
#### When using `with-compiler`
```
Error: [Cabal-5490]
Cannot find the program 'ghc'. User-specified path 'ghc-9.12' does not refer to an executable and the program is not on the system path.
```
Moreover, with the error codes, we are able to provide better feedback to the user regarding the reason `cabal` fails. Even this infamous search engine gives relevant results:

---
## This RFC
The point of this RFC is to argue in favour of changing the behaviour of `cabal init` in two ways:
* In non-interactive mode, prouce a `cabal.project` where the `with-compiler` stanza is set to the current GHC
* In interactive mode, prompt the user to enter a `ghc-xxx` string, with the current GHC's version as a default.
We can even add a link to the project file documentation as a comment in the first line.
The whole point is to improve a beginner's first steps in Haskell. Cloning a repository and getting a solver error when running `cabal build` is not people particularly enjoy, especially when they have to go on a wild goose chase to figure out which version of `base` is shipped with which version of `ghc`.
Should this RFC be accepted, I will implement it.
Contributor guide
Research direction
Start at the `cabal init` entry point and inspect how project files are generated in interactive and non-interactive modes. Run `cabal init` in both modes; done means a `cabal.project` is produced with the current GHC in `with-compiler`, and interactive mode prompts with that version as the default.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- haskell
- Domain
- build-system, cli
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100