概要
Haskellに興味があったので、AtCoderで入門してみることにした。環境構築でつまづいたので、備忘録として残しておく。
単一ファイルで動かしたいのでCabal Scriptを利用することにした。
Cabal Scriptとは
Haskellファイルの先頭に以下のようにライブラリの依存関係を設定できるので便利。
{- cabal:
build-depends: base, bytestring ^>= 0.11.3.1
-}
import qualified Data.ByteString.Char8 as BS
main = BS.putStrLn (BS.pack "Hello world!")
以下のように実行できる
> cabal run hellocabal.hs
Hello world!
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は必要ないかなと思ったので消してます、必要なら追加してください!)
{- 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でStackとかCabalとかGHCとか全部管理できます!
インストール方法は以下のコマンドを実行するだけ。
途中何回かインストール方法について聞かれます。
(わからなかったら A, Y, Y にしとけばいいと思います!)
curl --proto '=https' --tlsv1.2 -sSf https://get-ghcup.haskell.org | sh
参考リンク
インストール後のつまづきポイント
つまづきポイントは、
- GHCのバージョンを正しく設定する
- Cabalのバージョンを正しく設定する
- cabal updateしないとインストールできないライブラリがある
の3つです。
これが不適切だとこのようなエラーが出ます。
$ 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
対処法
AtCoderのライブラリに対応して次のように設定します。
- GHCはv9.4.5 (tagがbase-4.17.1.0)
- Cabalはv3.10.1.0以上
対応するversionは以下のコマンドで調べました。
ghcup list
出力結果
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
バージョンを変更するには以下のコマンドを利用します。
(インストールしてからそれを使うよう設定しています)
ghcup install <コマンド> <バージョン>
ghcup set <コマンド> <バージョン>
要するに以下を実行すればいいです。
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
プログラム実行
試しに以下のプログラムを実行してみましょう。
{- 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だとビルドの経過が見れなくて(?)不安です)
cabal build main.hs
正しくビルドできたら実行してみましょう!
> cabal run main.hs
"Hello World"
やったね!
参考文献
これを参考にしました。