2013年8月現在のHaskell開発環境

以前はHaskell Platformを使っていたのだけど、Cabalの依存関係ソルバがあまり賢くなかったこともあり、いわゆるdependency hellに陥ることが多かった。それからというものHaskell Platformを使わない環境を使っている。OS Xでは公式のインストーラやらHomebrewやMac Portsなど幾つかの方法が用意されているが、こんな方法もあるよということで紹介してみよう。

GHCのインストール

GHCのリリース版は自分でビルドしない。時間が掛かるから。インストーラは使わずにtarball版を使う。これはインストール先を自分で指定したいため。

tar zxvf ~/Downloads/ghc-7.6.3-x86_64-apple-darwin.tar.bz2
cd ghc-7.6.3/
./configure --prefix=/usr/local/ghc/ghc-7.6.3
make install

こんな感じで/usr/local/ghc/ghc-x.y.zにインストールする。今はこんな感じ。7.2.xがないのに特に深い意味はない。

[maoe@maoe:~]
% ls /usr/local/ghc/   
ghc-7.0.4 ghc-7.4.2 ghc-7.6.3 ghc-HEAD

HEADが欲しい場合は自分でビルドする。使いたくなったタイミングで更新してる。インストール先は/usr/local/ghc/ghc-HEAD。

Haskell Platformを使わない利点は、バージョンが固定されるパッケージが少ないので依存関係でこけることが減ること。逆に欠点はプロジェクトごとに必要なパッケージをビルド・インストールするのでインストール時間と容量を食うこと。気になる人はHaskell Platformを同じディレクトリにインストールすればいいのかもしれないが、試したことはない。

GHCの切り替え

基本的にはshellから単にPATHを切り替えるようにしている。会社で使われていたスクリプトを少しだけ弄って使っている*1

maoe/dotfilesにあるprepathpreghcをbashrcやzshrc的なものにコピーすれば使えると思う。使い方は簡単で、

preghc

とだけ打てば最新のリリース版に、

preghc 7.4
preghc HEAD

などで特定バージョンに切り替えられる。

エディタからGHCを呼びたい場合はシェルスクリプトの関数を呼ぶとトラブルの元になりかねないのでバージョン固定でPATHを指定した方がよいかもしれない。

cabal sandbox

ライブラリを入れる際にcabal installするのはやめよう。cabal install yesod-platformなんてした日にはきっとあなたの.cabalは悲惨なことになる。これまでcabal-devを使っていたけど、最近cabalコマンド自体にsandbox機能やsandboxからGHCiを起動する機能が実装されたので、githubのmasterブランチを取ってきてビルドして使い始めた。これがなかなか快適なのでおすすめ。

そのうちHackageに上がると思うけど先取りして紹介しよう。自分のプロジェクトのルートディレクトリにいって

cabal sandbox init

とすれば.cabal-sandboxディレクトリが作られる。後はいつも通りにコマンドを打てば依存しているパッケージはすべて.cabal-sandbox配下にインストールされ、グローバルあるいはユーザレベルのパッケージデータベースを壊すことはなくなる。

cabal install --only-dependencies # .cabal-sandboxに依存ライブラリをインストール
cabal configure
cabal build
cabal test
cabal bench

GHCiを立ち上げたかったら

cabal repl

とする。あなたのプロジェクトがlibraryであれば上のコマンドでライブラリのモジュールがロードされる。

例えばtest suiteを弄っているときにGHCiが欲しくなったとする。Cabalファイルに

test-suite regression-tests
  hs-source-dirs: tests
  -- ...

と書いてあったとすると

cabal repl regression-tests

とすればライブラリの代わりにそのtest suiteのモジュールがロードされる。

それから、もしあなたのプロジェクトが公開されていないライブラリに依存しているなら、cabal-devと同じようにadd-sourceコマンドが使える。ただし、cabal-devとは異なり*2tarballではなくディレクトリを指定する。

cabal sandbox add-source path/to/your/library/directory

*1:会社で使われているスクリプトもコレに差し替えた

*2:cabal-devではtarballもディレクトリでもOKだそうです。 @notogawa さんありがとうございます。