Haskell

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

More than 1 year has passed since last update.


あらまし



  • 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 した時に使えるパッケージが入る。