Skip to content

Commit 80ab27c

Browse files
authored
Merge pull request #162 from cherryblossom000/haskell-installation
add haskell installation instructions
2 parents 0effaca + 4d5ef0e commit 80ab27c

File tree

3 files changed

+298
-2
lines changed

3 files changed

+298
-2
lines changed

_chapters/haskell0.md

Lines changed: 259 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,259 @@
1+
---
2+
layout: chapter
3+
title: "Haskell Installation"
4+
---
5+
6+
## Learning Outcomes
7+
8+
- Install Haskell via GHCup and Stack
9+
10+
## Install GHCup
11+
12+
We will use [GHCup](https://www.haskell.org/ghcup/) to install and manage our tooling. The commands we will use to install GHCup differ slightly from the [official installation instructions](https://www.haskell.org/ghcup/install) in order to speed up the installation process.[^1]
13+
14+
- [Windows Instructions](#windows)
15+
16+
- [Non-Windows Instructions](#non-windows)
17+
18+
### Windows
19+
20+
Run this command in a PowerShell session:
21+
22+
``` ps1
23+
Set-ExecutionPolicy Bypass -Scope Process -Force;[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; try { & ([ScriptBlock]::Create((Invoke-WebRequest https://www.haskell.org/ghcup/sh/bootstrap-haskell.ps1 -UseBasicParsing))) -Interactive -DisableCurl -Minimal } catch { Write-Error $_ }
24+
```
25+
26+
In the installation process, select the following options (you might not be asked the first question if you do not have Chocolatey):
27+
28+
```none
29+
Chocolatey was detected on your system...
30+
Continue with GHCup installation?
31+
[C] Continue [A] Abort [?] Help (default is "C"): C
32+
33+
Where to install to (this should be a short Path, preferably a Drive like 'C:\')?
34+
If you accept this path, binaries will be installed into 'C:\ghcup\bin' and msys2 into 'C:\ghcup\msys64'.
35+
Press enter to accept the default [C:\]: (Enter)
36+
37+
Specify Cabal directory (this is where haskell packages end up)
38+
Press enter to accept the default [C:\\cabal]: (Enter)
39+
40+
Do you want to install the haskell-language-server (HLS) for development purposes as
41+
well?
42+
[Y] Yes [N] No [A] Abort [?] Help (default is "N"): N
43+
44+
Do you want to install stack as well?
45+
[Y] Yes [N] No [A] Abort [?] Help (default is "N"): N
46+
47+
Do you want to create convenience desktop shortcuts (e.g. for uninstallation and mysys2 shell)?
48+
[Y] Yes [N] No [A] Abort [?] Help (default is "Y"): N
49+
50+
Do you want GHCup to install a default MSys2 toolchain (recommended)?
51+
[Y] Yes [N] No [?] Help (default is "Y"): Y
52+
```
53+
54+
Run
55+
56+
``` sh
57+
ghcup --version
58+
```
59+
60+
to check that the installation has succeeded. You might need to restart your terminal first.
61+
62+
### Non-Windows
63+
64+
If you are on macOS and have Homebrew, you can install GHCup via Homebrew: `brew install ghcup`
65+
66+
If not, run this command in a terminal:
67+
68+
``` sh
69+
export BOOTSTRAP_HASKELL_MINIMAL=1 && curl --proto '=https' --tlsv1.2 -sSf https://get-ghcup.haskell.org | sh
70+
```
71+
72+
In the installation process, select the following options:
73+
74+
```none
75+
Do you want ghcup to automatically add the required PATH variable to "..."?
76+
77+
[P] Yes, prepend [A] Yes, append [N] No [?] Help (default is "P").
78+
79+
A
80+
```
81+
82+
Run
83+
84+
``` sh
85+
ghcup --version
86+
```
87+
88+
to check that the installation has succeeded. You might need to restart
89+
your terminal first.
90+
91+
## Install tools using GHCup
92+
93+
We will be installing the following tools:
94+
95+
- Stack: 3.7.1
96+
- HLS: 2.11.0.0
97+
98+
To do this, run
99+
100+
``` sh
101+
ghcup install --set stack 3.7.1
102+
ghcup install --set hls 2.11.0.0
103+
```
104+
105+
Alternatively, GHCup comes with a convenient TUI (terminal user interface):
106+
107+
``` sh
108+
ghcup tui
109+
```
110+
111+
Follow the instructions of the TUI to install (`i`) Stack and HLS and
112+
set (`s`) their versions to 3.7.1 and 2.11.0.0 respectively. Once this
113+
is done, you should see something like
114+
115+
```none
116+
┌──────────────────────────────────GHCup──────────────────────────────────┐
117+
│ Tool Version Tags Notes │
118+
│─────────────────────────────────────────────────────────────────────────│
119+
│✔✔ GHCup 0.1.50.2 latest,recommended │
120+
│─────────────────────────────────────────────────────────────────────────│
121+
│✔✔ Stack 3.7.1 latest │
122+
│✗ Stack 3.5.1 │
123+
│✗ Stack 3.3.1 recommended │
124+
│✗ Stack 3.1.1 │
125+
│✗ Stack 2.15.7 │
126+
│─────────────────────────────────────────────────────────────────────────│
127+
│✔✔ HLS 2.11.0.0 latest │
128+
│✗ HLS 2.10.0.0 recommended │
129+
│✗ HLS 2.9.0.1 │
130+
│✗ HLS 2.9.0.0 │
131+
│✗ HLS 2.8.0.0 │
132+
│✗ HLS 2.7.0.0 │
133+
│✗ HLS 2.6.0.0 │
134+
│─────────────────────────────────────────────────────────────────────────│
135+
```
136+
137+
If you only see 1 tick `` instead of 2 ticks `✔✔`, that means you have installed the tool but it is not set as your current/active version of that tool. To fix this, select the version and press `s` to set it.
138+
139+
## Check installation
140+
141+
Open the Haskell code bundle and run the following:
142+
143+
``` sh
144+
stack setup
145+
```
146+
147+
This normally takes a long time as Stack has to install GHC (the Haskell compiler). This command only needs to be run once in this unit: there’s no need to re-run it for each week’s applied exercises.
148+
149+
Once this is done, you can run the following to verify everything is installed correctly:
150+
151+
``` sh
152+
stack ghc -- --version
153+
```
154+
155+
which should output
156+
157+
```none
158+
The Glorious Glasgow Haskell Compilation System, version 9.8.4
159+
```
160+
161+
This may download any missing dependencies.
162+
163+
## VS Code Setup
164+
165+
Install the [Haskell extension](https://marketplace.visualstudio.com/items?itemName=haskell.haskell). This provides Haskell language support including language server, syntax highlighting, and linting.
166+
167+
### Optional Extras
168+
169+
These may take a while to install, so if you’re installing Haskell during your applied class, it is worth getting started on your applied session work instead.
170+
171+
- Formatter: [Fourmolu](https://github.com/fourmolu/fourmolu)
172+
- Install with `stack install fourmolu`
173+
- Set the ‘Haskell: Formatting Provider’ (`haskell.formattingProvider`) setting in VS Code to ‘fourmolu’
174+
175+
- Linter: [hlint](https://github.com/ndmitchell/hlint)
176+
- Install with `stack install hlint`
177+
- Ensure the ‘Haskell › Plugin › Hlint: Diagnostics On’ (`haskell.plugin.hlint.diagnosticsOn`) setting in VS Code is enabled, which should be the default
178+
179+
## Troubleshooting
180+
181+
### Windows Issues
182+
183+
#### `invalid argument (invalid character)`
184+
185+
If you get an error like this:
186+
187+
```none
188+
Error: [S-7282]
189+
Stack failed to execute the build plan.
190+
191+
While executing the build plan, Stack encountered the following errors:
192+
193+
<stderr>: commitAndReleaseBuffer: invalid argument (invalid character)
194+
```
195+
196+
Go to Settings → Time and Language → Language and Region → Administrative language Settings → Change System Locale... → and check ‘Use Unicode UTF-8’. You might need to restart your computer.
197+
198+
#### Spaces or special characters in username
199+
200+
If you get an error that looks like this:
201+
202+
```none
203+
Warning: [S-8432]
204+
Stack's 'programs' path is C:\Users\Your Name\AppData\Local\Programs\stack\. It contains a space character. This will prevent building with GHC 9.4.1 or later.
205+
206+
To avoid sucn problems, use the local-programs-path non-project specific configuration option to specify an alternative path without those characteristics.
207+
```
208+
209+
or if it says
210+
211+
```none
212+
It contains at least one non-ISO/IEC 8859-1 (Latin-1) character (Unicode code point > 255). This will cause problems with packages that build using the hsc2hs tool with its default template template-hsc.h.
213+
```
214+
215+
you need to change the `local-programs-path` Stack configuration option. To do this, edit `%AppData%\stack\config.yaml` (by default it will be something like `C:\Users\Your Name\AppData\Roaming\stack\config.yaml`). You can also do this by running the command
216+
217+
``` ps1
218+
notepad.exe $(stack path --global-config)
219+
```
220+
221+
Add the following line to the bottom of the file:
222+
223+
``` yml
224+
local-programs-path: C:\stack-programs
225+
```
226+
227+
### macOS Issues
228+
229+
If you get an error that looks something like `fatal error: 'ffi.h'`, it may be because you do not have the Xcode command line tools installed. (These are a collection of command line utilities and other developer tools that many programs rely on.) You can install them by running the following command in your terminal:
230+
231+
``` sh
232+
xcode-select --install
233+
```
234+
235+
If you have an existing (possibly broken) installation, you might need to get rid of it first:
236+
237+
``` sh
238+
sudo rm -rf /Library/Developer/CommandLineTools
239+
```
240+
241+
## Appendix: What are all these different tools?
242+
243+
If you are curious, here’s an explanation of the different Haskell build tools you may come across or hear about. (You do not need to know this.)
244+
245+
- [**GHC**](https://www.haskell.org/ghc): Glasgow Haskell Compiler, the most popular Haskell compiler.
246+
- [**Cabal**](https://www.haskell.org/cabal): a Haskell build tool that uses GHC to build Haskell packages, which are specified by a `.cabal` file.
247+
- [**Stack**](https://www.haskellstack.org): another Haskell build tool that wraps around Cabal. Configuration for Stack is in the `stack.yaml` file.
248+
- Stack provides package sets---a collection of packages that compile together---to make managing dependencies less troublesome. The package set is specified by the `resolver` key in `stack.yaml`. For example, if your program depends on package A v1 and package B v1, but package A v1 depends on package B v2, your code won’t compile. A Stack package set might specify to use v2 of package A (which depends on package B v2) and v2 of package B v2, which work together. This way, you only need to say ‘I want package A and package B’, and Stack takes care of the rest.
249+
- Importantly, a package set also relies on a specific version of GHC. In this unit, we have set it up so that Stack manages this for you and installs the correct version of GHC for you.
250+
- Because `.cabal` files can be tedious to write by hand, Stack supports an alternative format, [**hpack**](https://github.com/sol/hpack), in a `package.yaml` file. When you run a Stack command, Stack will automatically generate a `.cabal` file from this.
251+
- [**HLS**](https://haskell-language-server.readthedocs.io/en/stable): Haskell Language Server. This is the program that editors (e.g. the VS Code Haskell extension) need to give you nice IDE features. Different versions of HLS work with different versions of GHC, which are indicated by `hls-powered` in `ghcup tui`.
252+
- You might have noticed a `hie.yaml` file in the applied code bundles. This is [**hie-bios**](https://github.com/haskell/hie-bios), a way to tell editors information about the workspace so that the language server works.
253+
- [**GHCup**](https://www.haskell.org/ghcup): a tool that helps you install specific versions of GHC, Cabal, Stack, and HLS.
254+
255+
You may have noticed these instructions do not get you to install GHC directly via GHCup. This is because as mentioned above, we have set it up so that Stack installs the correct version of GHC for you. This means that if you want to run GHCi for example, you need to run `stack ghci` instead of just `ghci`.
256+
257+
(It is possible to install GHC globally so you can run `ghci` without having to put `stack` in front of it; however, by default, this will mean you have two copies of GHC installed on your machine! This is why we modified the GHCup installation process slightly from the official instructions so that it doesn’t automatically install GHC and other tools we don’t need. There is a way around this by setting [`system-ghc: true`](https://docs.haskellstack.org/en/stable/configure/yaml/non-project/#system-ghc) in Stack, but you must ensure that the version of GHC you have installed matches the Stack package set for your project.)
258+
259+
[^1]: The only difference from the official installation script is that we stop GHCup from installing GHC (by adding the `-Minimal` flag to the Windows install script or by setting the environment variable `BOOTSTRAP_HASKELL_MINIMAL=1` on Unix), which can take a long time. Instead, we will install GHC via Stack, which will ensure we always have the correct version of GHC needed.

_chapters/haskell1.md

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ If you would like a more gradual introduction, [“Haskell Programming from Firs
2121

2222
## Starting with the GHCi REPL
2323

24-
A good way to get started with Haskell is simply to experiment with the GHCi REPL (or Read Eval Print Loop). You can install GHC from [here](https://www.haskell.org/ghcup/).
24+
A good way to get started with Haskell is simply to experiment with the GHCi REPL (or Read Eval Print Loop).
2525

2626
Start by making a file: `fibs.hs`
2727

@@ -34,9 +34,42 @@ fibs n = fibs (n-1) + fibs (n-2) -- recursive definition
3434
Then load it into GHCi like so:
3535

3636
```bash
37-
ghci fibs.hs
37+
stack ghci fibs.hs
3838
```
3939

40+
<div class="alert-box alert-warning" markdown="1">
41+
**`stack ghci` vs `ghci`**
42+
43+
If you followed our [Haskell installation instructions](/haskell0), you will not have GHC installed globally, and will need to run `stack ghci` instead of just `ghci` on its own. This should work if you run the command from inside the folder for the applied exercises. If you run it outside of the folder, you might get this message:
44+
45+
```none
46+
Writing the configuration file for the implicit global project to:
47+
/Users/username/.stack/global-project/stack.yaml. Note: You can change the snapshot via
48+
the snapshot key there.
49+
Using the latest snapshot lts-24.7.
50+
51+
Error: [S-6362]
52+
No compiler found, expected minor version match with ghc-9.10.2 (aarch64) (based
53+
on the configuration in /Users/username/.stack/global-project/stack.yaml).
54+
55+
To install the correct version of GHC into the subdirectory for the specified
56+
platform in Stack's directory for local tools
57+
(/Users/username/.stack/programs/aarch64-osx/), try running stack setup or use
58+
the --install-ghc flag. To use your system GHC installation, run stack config set
59+
system-ghc --global true, or use the --system-ghc flag.
60+
```
61+
62+
To fix this, edit the `global-project/stack.yaml` file specified in the message above, change `resolver` to
63+
64+
```yml
65+
resolver: lts-23.25
66+
```
67+
68+
and then run `stack setup`.
69+
70+
If you are working in an Ed workspace (e.g. for workshops), Stack is not installed, so you will need to run `ghci` instead of `stack ghci`.
71+
</div>
72+
4073
You’ll get a prompt that looks like:
4174

4275
```haskell

_data/chapters.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,10 @@
7878
description: |
7979
- Compare a lambda-calculus-inspired Haskell-like language (PureScript) with the functional programming concepts explored earlier in JavaScript
8080
- Understand how tail call optimisation is applied in languages which support it
81+
- title: Haskell Installation
82+
url: /haskell0/
83+
description: |
84+
- Install Haskell via GHCup and Stack
8185
- title: Creating and Running Haskell Programs
8286
url: /haskell1/
8387
description: |

0 commit comments

Comments
 (0)