AtCoderを解くためのHaskell環境構築

# 概要
Haskellに興味があったので、AtCoderで入門してみることにした。環境構築でつまづいたので、備忘録として残しておく。
単一ファイルで動かしたいのでCabal Scriptを利用することにした。
<details><summary>Cabal Scriptとは</summary><div>

Haskellファイルの先頭に以下のようにライブラリの依存関係を設定できるので便利。
```haskell:hellocabal.hs
{- cabal:
build-depends: base, bytestring ^>= 0.11.3.1
-}
import qualified Data.ByteString.Char8 as BS
main = BS.putStrLn (BS.pack "Hello world!")
```
以下のように実行できる
```bash
> cabal run hellocabal.hs
Hello world!
```
参考文献
https://zenn.dev/mod_poppo/articles/haskell-script

</div></details>

## 2023年言語アップデート
- Language Test 202301
https://atcoder.jp/contests/language-test-202301
- 新ジャッジテストコンテスト -Algorithm-
https://atcoder.jp/contests/newjudge-2308-algorithm
- 使用できる言語とライブラリの一覧
https://img.atcoder.jp/file/language-update/language-list.html

一番最後のリンクにライブラリが書いてあるので、これと同じ環境を目指します。

### Cabal Scriptにつけるやつ
Cabal Scriptの形式にしたものがこれです。コピペして使ってください。
(Cabal ^>=3.10.1.0は必要ないかなと思ったので消してます、必要なら追加してください！）
```haskell
{- cabal:
build-depends: Cabal-syntax ^>=3.10.1.0, QuickCheck ^>=2.14.3, adjunctions ^>=4.4.2, array ==0.5.4.0, attoparsec ^>=0.14.4, base ==4.17.1.0, bifunctors ^>=5.6.1, binary ^>=0.8.9.1, bitvec ^>=1.1.4.0, bytestring ^>=0.11.4.0, comonad ^>=5.0.8, containers ^>=0.6.7, contravariant ^>=1.5.5, deepseq ==1.4.8.0, directory >=1.3.7.1 && <1.3.8.0, distributive ^>=0.6.2.1, exceptions ^>=0.10.7, extra ^>=1.7.13, fgl ^>=5.8.1.1, filepath >=1.4.2.2 && <1.4.99, free ^>=5.2, ghc-bignum ==1.3, ghc-boot-th ==9.4.5, ghc-prim ==0.9.0, hashable ^>=1.4.2.0, heaps ^>=0.4, indexed-traversable ^>=0.1.2.1, indexed-traversable-instances ^>=0.1.1.2, integer-gmp ^>=1.1, integer-logarithms ^>=1.0.3.1, kan-extensions ^>=5.2.5, lens ^>=5.2.2, linear-base ^>=0.3.1, list-t ^>=1.0.5.6, massiv ^>=1.0.4.0, megaparsec ^>=9.4.1, mono-traversable ^>=1.0.15.3, mtl ^>=2.3.1, mutable-containers ^>=0.3.4.1, mwc-random ^>=0.15.0.2, parallel ^>=3.2.2.0, parsec ^>=3.1.16.1, parser-combinators ^>=1.3.0, pretty ^>=1.1.3.6, primitive ^>=0.8.0.0, process ^>=1.6.17.0, profunctors ^>=5.6.2, psqueues ^>=0.2.7.3, random ^>=1.2.1.1, reflection ^>=2.1.7, regex-tdfa ^>=1.3.2.1, safe-exceptions ^>=0.1.7.3, scientific ^>=0.3.7.0, semialign ^>=1.3, semigroupoids ^>=6.0.0.1, split ^>=0.2.3.5, stm ^>=2.5.1.0, strict ^>=0.5, strict-lens ^>=0.4.0.3, tagged ^>=0.8.7, template-haskell ==2.19.0.0, text ^>=2.0.2, tf-random ^>=0.5, these ^>=1.2, these-lens ^>=1.0.1.3, time ^>=1.12.2, transformers ^>=0.6.1.0, trifecta ^>=2.1.2, unboxing-vector ^>=0.2.0.0, unix ==2.7.3, unordered-containers ^>=0.2.19.1, utility-ht ^>=0.0.17, vector ^>=0.13.0.0, vector-algorithms ^>=0.9.0.1, vector-stream ^>=0.1.0.0, vector-th-unbox ^>=0.2.2, xhtml ^>=3000.2.2.1
-}
```

## GHCupで環境構築
### 概要
[GHCup](https://www.haskell.org/ghcup/)でStackとかCabalとかGHCとか全部管理できます！
インストール方法は以下のコマンドを実行するだけ。
途中何回かインストール方法について聞かれます。
（わからなかったら A, Y, Y にしとけばいいと思います！）
```
curl --proto '=https' --tlsv1.2 -sSf https://get-ghcup.haskell.org | sh
```

参考リンク

https://zenn.dev/mod_poppo/articles/haskell-setup-2023

### インストール後のつまづきポイント
つまづきポイントは、
- GHCのバージョンを正しく設定する
- Cabalのバージョンを正しく設定する
- cabal updateしないとインストールできないライブラリがある

の3つです。
<details><summary>これが不適切だとこのようなエラーが出ます。</summary><div>

```bash
$ cabal build main.hs
Resolving dependencies...
Error: cabal: Could not resolve dependencies:
[__0] trying: fake-package-0 (user goal)
[__1] next goal: base (dependency of fake-package)
[__1] rejecting: base-4.16.4.0/installed-4.16.4.0 (conflict: fake-package =>
base==4.17.1.0)
[__1] skipping: base-4.18.0.0, base-4.17.2.0 (has the same characteristics
that caused the previous version to fail: excluded by constraint '==4.17.1.0'
from 'fake-package')
[__1] rejecting: base-4.17.1.0, base-4.17.0.0, base-4.16.4.0, base-4.16.3.0,
base-4.16.2.0, base-4.16.1.0, base-4.16.0.0, base-4.15.1.0, base-4.15.0.0,
base-4.14.3.0, base-4.14.2.0, base-4.14.1.0, base-4.14.0.0, base-4.13.0.0,
base-4.12.0.0, base-4.11.1.0, base-4.11.0.0, base-4.10.1.0, base-4.10.0.0,
base-4.9.1.0, base-4.9.0.0, base-4.8.2.0, base-4.8.1.0, base-4.8.0.0,
base-4.7.0.2, base-4.7.0.1, base-4.7.0.0, base-4.6.0.1, base-4.6.0.0,
base-4.5.1.0, base-4.5.0.0, base-4.4.1.0, base-4.4.0.0, base-4.3.1.0,
base-4.3.0.0, base-4.2.0.2, base-4.2.0.1, base-4.2.0.0, base-4.1.0.0,
base-4.0.0.0, base-3.0.3.2, base-3.0.3.1 (constraint from non-upgradeable
package requires installed instance)
[__1] fail (backjumping, conflict set: base, fake-package)
After searching the rest of the dependency tree exhaustively, these were the
goals I've had most trouble fulfilling: base, fake-package
```

</div></details>

### 対処法
AtCoderのライブラリに対応して次のように設定します。

- GHCはv9.4.5 (tagがbase-4.17.1.0)
- Cabalはv3.10.1.0以上

対応するversionは以下のコマンドで調べました。
```
ghcup list
```
<details><summary>出力結果</summary><div>

TagsとかVersionのカラムを見てください。
```
[ Warn  ] New ghc version available. If you want to install this latest version, run 'ghcup install ghc 9.6.2'
[ Warn  ] New stack version available. If you want to install this latest version, run 'ghcup install stack 2.11.1'
   Tool  Version  Tags                      Notes
✗  ghc   7.10.3   base-4.8.2.0              no-bindist
✗  ghc   8.0.2    base-4.9.1.0              no-bindist
✗  ghc   8.2.2    base-4.10.1.0             no-bindist
✗  ghc   8.4.1    base-4.11.0.0             no-bindist
✗  ghc   8.4.2    base-4.11.1.0             no-bindist
✗  ghc   8.4.3    base-4.11.1.0             no-bindist
✗  ghc   8.4.4    base-4.11.1.0             no-bindist
✗  ghc   8.6.1    base-4.12.0.0             no-bindist
✗  ghc   8.6.2    base-4.12.0.0             no-bindist
✗  ghc   8.6.3    base-4.12.0.0             no-bindist
✗  ghc   8.6.4    base-4.12.0.0             no-bindist
✗  ghc   8.6.5    base-4.12.0.0             no-bindist
✗  ghc   8.8.1    base-4.13.0.0             no-bindist
✗  ghc   8.8.2    base-4.13.0.0             no-bindist
✗  ghc   8.8.3    base-4.13.0.0             no-bindist
✗  ghc   8.8.4    base-4.13.0.0             no-bindist
✗  ghc   8.10.1   base-4.14.0.0             no-bindist
✗  ghc   8.10.2   base-4.14.1.0             no-bindist
✗  ghc   8.10.3   base-4.14.1.0             no-bindist
✗  ghc   8.10.4   base-4.14.1.0             no-bindist
✗  ghc   8.10.5   base-4.14.2.0
✗  ghc   8.10.6   base-4.14.3.0
✗  ghc   8.10.7   base-4.14.3.0             hls-powered
✗  ghc   9.0.1    base-4.15.0.0             no-bindist
✗  ghc   9.0.2    base-4.15.1.0
✗  ghc   9.2.1    base-4.16.0.0
✗  ghc   9.2.2    base-4.16.1.0
✗  ghc   9.2.3    base-4.16.2.0
✗  ghc   9.2.4    base-4.16.3.0
✗  ghc   9.2.5    base-4.16.4.0
✗  ghc   9.2.6    base-4.16.4.0
✗  ghc   9.2.7    base-4.16.4.0
✔✔ ghc   9.2.8    recommended,base-4.16.4.0 hls-powered
✗  ghc   9.4.1    base-4.17.0.0
✗  ghc   9.4.2    base-4.17.0.0
✗  ghc   9.4.3    base-4.17.0.0
✗  ghc   9.4.4    base-4.17.0.0
✓  ghc   9.4.5    base-4.17.1.0             hls-powered
✗  ghc   9.4.6    base-4.17.2.0             hls-powered
✗  ghc   9.4.7    base-4.17.2.0             hls-powered
✗  ghc   9.6.1    base-4.18.0.0
✗  ghc   9.6.2    latest,base-4.18.0.0      hls-powered
✗  cabal 2.4.1.0                            no-bindist
✗  cabal 3.0.0.0                            no-bindist
✗  cabal 3.2.0.0                            no-bindist
✗  cabal 3.4.0.0
✗  cabal 3.4.1.0
✗  cabal 3.6.0.0
✓  cabal 3.6.2.0  recommended
✗  cabal 3.8.1.0
✔✔ cabal 3.10.1.0 latest
✗  hls   1.1.0                              no-bindist
✗  hls   1.2.0                              no-bindist
✗  hls   1.3.0                              no-bindist
✗  hls   1.4.0
✗  hls   1.5.0
✗  hls   1.5.1
✗  hls   1.6.0.0
✗  hls   1.6.1.0
✗  hls   1.7.0.0
✗  hls   1.8.0.0
✗  hls   1.9.0.0
✗  hls   1.9.1.0
✗  hls   1.10.0.0
✗  hls   2.0.0.0
✗  hls   2.0.0.1
✗  hls   2.1.0.0
✔✔ hls   2.2.0.0  latest,recommended
✗  stack 2.5.1                              no-bindist
✗  stack 2.7.1                              no-bindist
✗  stack 2.7.3                              2022-02-02
✗  stack 2.7.5
✗  stack 2.9.1
✔✔ stack 2.9.3    recommended
✗  stack 2.11.1   latest
✔✔ ghcup 0.1.19.4 latest,recommended
```

</div></details>

バージョンを変更するには以下のコマンドを利用します。
(インストールしてからそれを使うよう設定しています）
```bash
ghcup install <コマンド> <バージョン>
ghcup set <コマンド> <バージョン>
```
要するに以下を実行すればいいです。
```bash
ghcup install ghc 9.4.5
ghcup set ghc 9.4.5

ghcup install cabal 3.10.1.0
ghcup set cabal 3.10.1.0
```
Cabalのバージョン設定後に、ライブラリの情報を最新にするため、以下のコマンドを実行しておいてください。
(実行しないと、僕の環境では一部のライブラリが取得できませんでした）
```
cabal update
```
## プログラム実行
試しに以下のプログラムを実行してみましょう。
```haskell:main.hs
{- cabal:
build-depends: Cabal-syntax ^>=3.10.1.0, QuickCheck ^>=2.14.3, adjunctions ^>=4.4.2, array ==0.5.4.0, attoparsec ^>=0.14.4, base ==4.17.1.0, bifunctors ^>=5.6.1, binary ^>=0.8.9.1, bitvec ^>=1.1.4.0, bytestring ^>=0.11.4.0, comonad ^>=5.0.8, containers ^>=0.6.7, contravariant ^>=1.5.5, deepseq ==1.4.8.0, directory >=1.3.7.1 && <1.3.8.0, distributive ^>=0.6.2.1, exceptions ^>=0.10.7, extra ^>=1.7.13, fgl ^>=5.8.1.1, filepath >=1.4.2.2 && <1.4.99, free ^>=5.2, ghc-bignum ==1.3, ghc-boot-th ==9.4.5, ghc-prim ==0.9.0, hashable ^>=1.4.2.0, heaps ^>=0.4, indexed-traversable ^>=0.1.2.1, indexed-traversable-instances ^>=0.1.1.2, integer-gmp ^>=1.1, integer-logarithms ^>=1.0.3.1, kan-extensions ^>=5.2.5, lens ^>=5.2.2, linear-base ^>=0.3.1, list-t ^>=1.0.5.6, massiv ^>=1.0.4.0, megaparsec ^>=9.4.1, mono-traversable ^>=1.0.15.3, mtl ^>=2.3.1, mutable-containers ^>=0.3.4.1, mwc-random ^>=0.15.0.2, parallel ^>=3.2.2.0, parsec ^>=3.1.16.1, parser-combinators ^>=1.3.0, pretty ^>=1.1.3.6, primitive ^>=0.8.0.0, process ^>=1.6.17.0, profunctors ^>=5.6.2, psqueues ^>=0.2.7.3, random ^>=1.2.1.1, reflection ^>=2.1.7, regex-tdfa ^>=1.3.2.1, safe-exceptions ^>=0.1.7.3, scientific ^>=0.3.7.0, semialign ^>=1.3, semigroupoids ^>=6.0.0.1, split ^>=0.2.3.5, stm ^>=2.5.1.0, strict ^>=0.5, strict-lens ^>=0.4.0.3, tagged ^>=0.8.7, template-haskell ==2.19.0.0, text ^>=2.0.2, tf-random ^>=0.5, these ^>=1.2, these-lens ^>=1.0.1.3, time ^>=1.12.2, transformers ^>=0.6.1.0, trifecta ^>=2.1.2, unboxing-vector ^>=0.2.0.0, unix ==2.7.3, unordered-containers ^>=0.2.19.1, utility-ht ^>=0.0.17, vector ^>=0.13.0.0, vector-algorithms ^>=0.9.0.1, vector-stream ^>=0.1.0.0, vector-th-unbox ^>=0.2.2, xhtml ^>=3000.2.2.1
-}
main :: IO ()
main = do
  print "Hello World"
```
初回はビルドに時間がかかるので、buildコマンドを使って進捗を見守ります。
(runだとビルドの経過が見れなくて（？）不安です）

```bash
cabal build main.hs
```
正しくビルドできたら実行してみましょう！

```bash
> cabal run main.hs
"Hello World"
```

やったね！

# 参考文献
これを参考にしました。

https://zenn.dev/mod_poppo/articles/haskell-script

https://zenn.dev/mod_poppo/articles/haskell-setup-2023