Haskell Advent Calendar 2021, 7 日目の記事です。
はじめに - stack script はいいぞ
Haskell を触り始めてだいぶ経ちますが、ようやく完全に理解した(分かってない)ので何かにつけて Haskell を使いたくなります。
しかしそうほいほいネタが出てくる程に発想が豊かなわけではありません。まさに「Twitterを巡回していてわかったHaskell初心者が躓きやすいポイント8つ」のうちの一つにはまってしまいそうになっていました。
そんな時、ちょっとしたスクリプトを Haskell で書いてみることに私は活路を見出しました。普段つい Bash や Python で書いちゃっているようなものを Haskell で書いちゃうわけです。そして Haskell ではそれが出来ます。stack script
という便利なコマンドがあるのです。
ただ本記事ではその詳細については触れません。stack script
コマンドの使い方については、例えば以下をご覧ください。
stack script は専用のディレクトリを用意することなくそのファイルだけで完結できるので、大変重宝します。しかし本当にファイル一つだけでスクリプトを書いていると HLS がうまく起動してくれないという不都合がありました。というわけで、ここからが本記事の本題。
環境
- OS: Windows 11
- stack: winget 経由でインストール
- エディタ: VS Code
- プラグイン:
- Haskell for Visual Studio Code
- Haskell Syntax Highlighting
最近 Windows を 11 にアップグレードしました。ついでに winget を導入しました。ただ winget では GHC を直接インストール出来ないのでそのせいではまったというのもありそうです。
出てくるエラーと解消方法
仮に、スクリプトのファイルしかないディレクトリを VS Code で開いたとします。すると右下にすぐにエラーが表示されます。
Project requires GHC but isn't installed
最初に出てくるエラーはこれです。エラーメッセージの通り、HLS が GHC を認識できていないです。これの解消法は二つあります。
1. パスを通す
Windows であれば、コントロールパネルから環境変数に stack によってインストールされた GHC にパスを通すことで解消することが出来ます。Linux などであれば .bashrc かなにかでパスを追加すればいいかもしれません。stack path
コマンドを実行して表示される、compiler-bin
のパスがこれに該当します。
この方法を使えば、それだけで HLS はちゃんと起動します。別のエラーが出てくることもないですし、そのために後述するような余計なファイルを作る必要もありません。
しかし環境変数に設定すべきパスは GHC のバージョンによって異なっており、GHC のバージョンを変更したり何らかの事情で少し古い resolver でスクリプトを書きたくなったらいちいち環境変数を変更しなければならないでしょう。これでは面倒です。
というわけで、他の方法を考えます。
2. stack.yaml を作る
ここで普通に stack new
して作った場合を思い出してみます。この場合 HLS はプロジェクトで使っている GHC のパスをバージョン含め自動で認識し、ソースコードを解析してくれます。したがって stack new
で作成される何らかのファイルの存在が重要であると推測されます。
GHC のバージョンまで特定可能な情報といえば stack の resolver です。そして resolver が記載されたファイルといえば、stack.yaml ですね。実際、以下の内容の stack.yaml を作ればこのエラーは出なくなります。
resolver: lts-18.18
packages: []
resolver のバージョンはスクリプトで使うものとそろえたほうがいいでしょう。また packages は空配列を指定しないとまたさらに別のエラーが出てきます。
Couldn't figure out what GHC version the project is using: ...
stack.yaml を作ったことで GHC が見つからないというエラーは解消することが出来ましたが、それだけでは HLS は起動してくれませんでした。今度は GHC のバージョンはどれを使えばいいのかわからないと言ってきます。
stack.yaml に resolver のバージョンも書いているので分かりそうなものですが、エラーメッセージの続きを読むと以下のように書かれています。
No 'hie.yaml' found. Try to discover the project type! Failed get project GHC version, since we have a none cradle
なので hie.yaml を作りましょう。stack を使っていますから、以下の内容で1。
cradle:
stack:
そしてエディタを再起動すれば、今度こそ HLS ちゃんが起動してスクリプトにダメだししてくれるようになります。やったね!
まとめ
stack script はちょっとしたプログラムを書きたいときに重宝しますが、スクリプト編集中そのままでは HLS がうまく起動してくれず不便でした。解消法を考えた結果、以下のファイルを用意すればスクリプト編集中も HLS にお世話してもらえるようになりました。
- stack.yaml
- hie.yaml
ただこれらのファイルをいちいち用意しなければならないためやはりちょっと面倒です。他にもっとよい方法がありましたら教えてもらえるとうれしいです。