はじめに
先日、自宅のMacBook ProのmacOSをクリーンインストールしつつCatalinaにアップデートしました。
まっさらな環境に一から環境構築していくのは楽しい作業ではあるのですが、Haskellの環境に関しては数ヶ月前に試行錯誤の末に構築したこともあり全然整理できていなくて、この機会に手順を書いておこうかなと思います。
環境
- macOS 10.15 (Catalina)
- Stack 2.1.3
- GHC 8.6.5
- Haskell IDE Engine 0.12.0.0
- Visual Studio Code 1.39.2
前提
macOSに以下のソフトウェアがインストール済みであること。
- Homebrew
- Visual Studio Code(以下、VSCodeと記す)
作成する環境について
これから作成する環境は、VSCodeでIDEのような操作感を手に入れたうえで、IntelliJ IDEAの操作感をちょい足ししたような環境を目指します。
そのためには以下のツールを使用します。
Haskell IDE Engine
Haskell IDE Engine は、Language Server Protocol を介して、普通のテキストエディタにIDEのようなコード補完やコンパイルエラーの表示などの機能を追加できるツールです。操作イメージは、公式の この辺 を見ると分かりやすいと思います。
なお、Haskell IDE Engineは、今のところバイナリ形式での配布はされていないため、GitHubからソースコードを落として手元の環境でビルドする必要があります。ビルド時間はそれなりに掛かります。
IntelliJ IDEA Key Bindings
IntelliJ IDEA Key Bindings は、VSCodeのキーバインディングをIntelliJ IDEAのそれに置き換えるVSCodeのextensionsです。
これを使用すると、例えばVSCode上のターミナルの開閉は Option+F12
で、プロジェクトウィンドウの開閉は Command+1
でという風に、IntelliJ IDEAのショートカットキーがVSCodeでも使えるようになります。詳しい使い方は、 こちら に記載されています。
そもそもなぜこの環境にしたのか
私は普段の開発にIntelliJ IDEAやAndroid Studioなど、JetBrains製品を愛用しています。そのためHaskellもIntelliJ IDEAで書きたかったのですが、専用のpluginである IntelliJ Haskell がどうも自分には合わなくて、それとHaskell IDE Engineとの出会いもあったため普段補助的に使用しているVSCodeでHaskellを書くことにしました。
ただ、個人的にVSCodeの素のキーバインディングはいまいち馴染めなくて、JetBrains製品との行き来にどうしても脳内コンテキストスイッチが発生してしまいます。これを防ぐために、IntelliJ IDEA Key Bindingsを使用することにしました。
前置きが長くなりましたが、次項からは手順を書いていきたいと思います。
構築手順
1. Stackをインストール
まずは、Homebrewを使用して Stack をインストールします。 Stackは、Haskellのビルド&パッケージ管理ツールで、プロジェクト毎のGHCや依存パッケージのバージョン管理などができます。
$ brew install haskell-stack $ stack —version Version 2.1.3 x86_64
2. PATH
の追加
Stackでインストールする各種実行ファイルは、 ~/.local/bin
に保存されます。
そのため、 ~/.local/bin
を PATH
に追加しておきます。
- bashの場合
$ echo 'export PATH=~/.local/bin:$PATH' >> ~/.bashrc
- fishの場合
$ echo 'set -x PATH ~/.local/bin $PATH' >> ~/.config/fish/config.fish
3. stackコマンドの自動補完を設定
ログインシェルを bash
か zsh
にしている場合は、 Shell Auto-completion を設定しておくことで、Stackのサブコマンドを自動補完してくれるようになります。以下はbashの例。
$ echo 'eval "$(stack --bash-completion-script stack)"' >> ~/.bashrc
Shell Auto-completionは、残念ながら fish
では未対応のようですね。
4. stack update
以下のコマンドを叩き、 ~/.stack
内のグローバルプロジェクトのフォルダを生成しておきます。
$ stack update $ tree ~/.stack -L 2 /Users/xxx/.stack ├── config.yaml ├── global-project │ ├── README.txt │ ├── stack.yaml │ └── stack.yaml.lock ├── pantry │ ├── hackage │ ├── pantry.sqlite3 │ └── pantry.sqlite3.pantry-write-lock ├── programs │ └── x86_64-osx ├── setup-exe-cache │ └── x86_64-osx ├── setup-exe-src │ ├── setup-mPHDZzAJ.hi │ ├── setup-mPHDZzAJ.hs │ ├── setup-mPHDZzAJ.o │ ├── setup-shim-mPHDZzAJ.hi │ ├── setup-shim-mPHDZzAJ.hs │ └── setup-shim-mPHDZzAJ.o ├── snapshots │ └── x86_64-osx ├── stack.sqlite3 └── stack.sqlite3.pantry-write-lock
5. Haskell IDE Engineをインストール
Haskell IDE Engineをインストールする前に GMP(多倍長演算ライブラリ) を再インストールしておきます。これをやっておかないと、Haskell IDE Engineのビルドの途中でエラーになってしまいます。
$ brew reinstall gmp
Haskell IDE Engineは前述の通りバイナリ形式では配布されていないので、 GitHub からソースコードを落として手元の環境でビルドする必要があります。
まずはgit cloneして、haskell-ide-engineへchange directoryします。
$ git clone https://github.com/haskell/haskell-ide-engine --recurse-submodules $ cd haskell-ide-engine
取りあえずhelpを確認してみましょう。
$ stack ./install.hs help run from: stack Usage: stack install.hs <target> or cabal new-run install.hs --project-file install/shake.project <target> Targets: help Show help message including all targets build Builds hie with all installed GHCs build-all Builds hie for all installed GHC versions and the data files build-data Get the required data-files for `hie` (Hoogle DB) hie-8.2.2 Builds hie for GHC version 8.2.2 hie-8.4.2 Builds hie for GHC version 8.4.2 hie-8.4.3 Builds hie for GHC version 8.4.3 hie-8.4.4 Builds hie for GHC version 8.4.4 hie-8.6.1 Builds hie for GHC version 8.6.1 hie-8.6.2 Builds hie for GHC version 8.6.2 hie-8.6.3 Builds hie for GHC version 8.6.3 hie-8.6.4 Builds hie for GHC version 8.6.4 hie-8.6.5 Builds hie for GHC version 8.6.5 ・・・省略・・・
helpの内容を見ると、GHCのそれぞれのバージョンに対応したHaskell IDE Engineが用意されていることが確認できます。今回は執筆時点の最新である 8.6.5
を指定します。
$ stack ./install.hs hie-8.6.5 $ stack ./install.hs build-data
ちなみに、ここで build-all
を指定してしまうと、すべてのGHCのバージョンに対してHaskell IDE Engineをインストールしてしまうので、恐ろしく時間が掛かってしまいます。使用するGHCのバージョンが決まっているのであれば、バージョン指定するのが無難です。
しばらく待っていると、こういう表示が出れば完了です。私の環境で約42分掛かりました。
Copied executables to /Users/xxx/.local/bin: - hie - hie-wrapper # stack (for stack-hie-8.6.5) Build completed in 42m15s $ hie --version Version 0.12.0.0, Git revision 3ec201f76d17148f67efb02672382109342ce391 (3037 commits) x86_64 ghc-8.6.5
6. VSCodeにextensionsを追加
VSCodeのextensionsに以下を追加します。
7. hoogleのセットアップ
最後にhoogleとの同期をできるように以下のコマンドを叩きます。
$ stack install hoogle --resolver lts $ hoogle generate
8. 完了
手順は以上です。ここまでの手順を終えると、VSCodeで こういう操作 ができるようになっているはずです!
おわりに
Haskellを本格的に学ぶようになって半年くらい経ちますが、HaskellはIDEやツールがまだまだ成熟していないのかなと感じています。そのため今はこの環境が自分にとって良い選択でも、状況はどんどん変わっていくと思うので、より良い環境は継続的に探していきたいと思います。