Haskell Stack のグローバル環境を雑に使う

あらまし

  • Stack は、Haskell のビルドツールのひとつ。
    • パッケージ群のバージョンを固定 (snapshot) することで Cabal hell が起こらなくなっている。
    • あくまでもビルドツールなのでプロジェクトを作ってその中で使うのが普通
    • しかしちょっとしたコード片のためにプロジェクトの環境構築するのは面倒。
    • グローバル環境を雑に使ってみたい(そういう使い方はあまり想定されていないかもしれないが)
  • Intero のようなモダンな IDE 環境を使ってみたい。
    • Intero は Stack の GHC を見ているようだ。つまり、プロジェクトの外で起動するとグローバルの Stack 環境で起動する。
    • 適当に拾ってきたコードを読む時にも Stack のグローバル環境は使えそうだ

現時点 (2018年4月) で雑に試した内容を書いておく。環境は macOS です。

既存の GHC を消す

色々とややこしいので ghcghci にパスが通っていない状態にする。 ついでに古い cabal や ~/.cabal も消した。

Stack のインストール

curl -sSL https://get.haskellstack.org/ | sh
stack upgrade

LTS バージョンの選定と Stack グローバル環境の構築

Stackage のトップページに新しめの GHC バージョンが揃っているので、適当な GHC を選び、それに対応する LTS のバージョンを控えておく。自分は lts-7.24 (LTS 7.24 for GHC 8.0.1, published 10 months ago) というのを選んだ。

Stack の環境は ~/.stack に構築される。ここに何もないことを確認して、 stack setup を起動。すぐに ^C で止める。

$ stack setup
^C

生成された ~/.stack/global-project/stack.yaml を編集し自分の好きな LTS のバージョンに変え、 stack setup を再実行

$ cat ~/.stack/global-project/stack.yaml 
packages: []
resolver: lts-7.24
$ stack setup

Intero のインストール

公式 の通り。 ~/.emacs/init.el に以下を書いた。

;; If you don't have MELPA in your package archives:
(require 'package)
(add-to-list
  'package-archives
  '("melpa" . "http://melpa.org/packages/") t)
(package-initialize)
(package-refresh-contents)

;; Install Intero
(package-install 'intero)
(add-hook 'haskell-mode-hook 'intero-mode)

GHC の起動

そのままでは当然 ghc などのコマンドが通らない。 stack ghc 等で起動できる。
あるいは、

stack exec bash -- --login

として stack の下で新しいシェルに入れば ghc にパスが通るようになる。 コマンドへのオプションは -- の後に置くことに注意する。 stack exec CMD -- オプション のようにする。
ただ、stack ghci が experimental ということなので この bash 環境もどこまで使えるのか??

パッケージのインストール?

stack build にパッケージ名を直接指定すればグローバル環境の Stack にパッケージが入る (Intero からも見えるようになる)。

stack build パッケージ名

Stack にはインストールという概念は無い(コマンドとしては存在するが stack build --copy-bins のエイリアスになっている)。その代わりに stack.yaml に書かれたパッケージが stack build 時にビルドされる。
今回は Stack をグローバル環境で使っているので、 ~/.stack/global-project/stack.yaml に書けば良さそうだが、ビルド対象のプロジェクトが無いので素の stack build は効かない。
上記のようにすればグローバルで stack ghc した時に使えるパッケージが入る。