Mac OS XのためのHaskell開発環境
はじめに
2012年ごろにとてもHaskellが流行り、たくさんの入門記事が書かれたものの、最近は関数型言語の物珍しさもあまりなくなり、むしろScalaやらC++11やらPythonの形に関数型の手法が定着しつつあるように感じます。
そんな中で出されたO'REILLY本「Haskellによる並列・並行プログラミング」を読み始めたわけですが、サンプルを動かそうとすると、これまでcabal install
でホイホイしてきたせいで多くのパッケージの依存関係が壊れていてイライラする。
というわけでHaskellの恐らく今最もスタンダードな環境構築を一からやり直したので、知っておいた方がいい情報と合わせてメモしてみました。 OSはMac OS X Mavericks (10.9.4)です。
GHC・Cabalのインストール
Haskellコンパイラの定番GHCとパッケージ管理ツールCabalのインストールです。Mac OSなので素直にHomebrewでインストールしました。Linux環境でもapptitudeやyumで簡単にインストールできるはず。
$ brew install ghc cabal-install
結構時間がかかるかと思いますが、特にエラーなくインストール出来ました。
なにか怒られてもエラーを読んだりbrew doctor
してみたりすればすぐに出来るかと思います。
ちなみにインストールできたバージョンは + GHC version 7.8.3 + Cabal library 1.20.0.2 + cabal-install 1.20.0.3 でした。
また、インストールしたcabal
コマンドを使うために.bash_profile
などお使いのシェルの起動時スクリプトで$HOME/.cabal/bin
を環境変数PATH
に追加しておくと楽でしょう。
GHCの使い方
GHCはghc
コマンドでソースコードのコンパイルが出来る他、ghci
コマンドで対話的な実行環境として実行できます。
主にghci
コマンドは後述するcabal repl
越しに関数の動き方の確認などに使用することとなるでしょう。
また、ghcコマンドにはGCCと同じように多彩なオプションが用意されています。 詳細はGHCのマニュアルを見ればわかりますが、以下に便利なオプションをいくつか書いておきます。
-o
$ ghc -o hoge Hoge.hs
基本ですが、一応。出力する実行ファイルの名前を指定します。 指定しない場合の出力ファイル名はmain関数を含むソースファイルのサフィックスを除いたものとなります。
-On
最適化オプションです。0~2の3段階があり、0は最適化なし、2は可能な限り最適化。指定しない場合は1となります。
-S
$ ghc -S Hoge.hs
...お楽しみオプションです。 ソースコードのコンパイルをアセンブルする前の状態(=アセンブリファイルを生成した状態)で止めます。 これによってGHCがどんなアセンブリを生成しているのか知ることができますが、ちょっとしたコードでもかなりの行数となるため、アセンブリコードからプログラムの性能を予測する、というのは現実的ではないかと思います。
ちなみに、GCCと同じように-c
オプションでリンク前までコンパイルすることもできますが、GHCでは渡されたソースコードにmain関数が含まれていなかった場合は自動的にオブジェクトの生成まででストップするため、断片コードのコンパイル時に明示的に-c
を付ける必要はありません。
cabalの使い方
Cabalを使うとRubyのBundlerのようにパッケージを管理することができます。 以下によく使用するコマンドを列挙しておきます。 なお、各コマンドのさらなる詳細は
$ cabal <コマンド名> --help
とするとみることができます。
init
$ cabal init
とすると対話的に自分の作成するプロジェクトのための.cabal
ファイルを作成することができます。
configure, build
$ cabal configure $ cabal build
とするとカレントディレクトリのプロジェクトを.cabal
ファイルに基づいてビルドすることができます。
Makefileよりも最適化された形があるのはとても嬉しいですね。
update
$ cabal update
とすると最新のパッケージリストを取得できます。パッケージのインストールを行う前に実行します。
list
$ cabal list <文字列>
とするとbrew search
のように<文字列>
にマッチするcabalでインストール可能なパッケージの一覧が取得できます。
info
$ cabal info <パッケージ名>
とするとbrew info
のように<パッケージ名>
で指定したパッケージの詳細を表示します。
sandbox
$ cabal sandbox init
とするとbundle install
の--path
オプションのようにカレントディレクトリ以下でパッケージを個別に管理します(かつては同様の目的でcabal-dev
パッケージが使用されていました)。
sandboxを指定せずにcabal install
をしてしまうと、プロジェクトごとに使用するパッケージのバージョンを管理できなくなるため、ひどいことになります。
パッケージのインストール前には必ずプロジェクト用のディレクトリを作成し、cabal sandbox init
を叩くようにしましょう。
install
$ cabal install <パッケージ名>
とすると<パッケージ名>
で指定したパッケージをインストールします。
前述のsandboxを使用していると、sandboxで指定されたディレクトリ(デフォルトでは./.cabal-sandbox
)以下にパッケージがインストールされます。
-jn
などとすると-jn
のn
で指定した数のジョブを同時に実行してくれるため、コアをフルに使ってインストールすることができます。
exec
$ cabal exec <コマンド名> -- <オプション>
とすると<コマンド名>
で指定したsandbox内にインストールしたパッケージの実行ファイル(デフォルトでは./cabal-sandbox/bin
以下にあるもの)を<オプション>
付きで実行できます。
これもRubyのBundlerと似た機能ですね。
repl
$ cabal repl
とすると、カレントディレクトリのsandboxにインストールしたパッケージと.cabal
ファイルで指定されているmain関数のあるファイルをロードしたghci
を起動することができます。
これはパッケージで提供されている関数などの挙動を確認する上で一番手っ取り早く、便利な方法になります。
ghc-pkgの使い方
ghc-pkg
コマンドでインストール済みのパッケージに対する操作を行うことができます。
こちらも以下によく使うものを列挙しておきます。
list
$ ghc-pkg list
とすると、グローバルスコープのインストール済みパッケージを一覧できます。
この時、ghcのインストール場所のpackage.conf.d
と$HOME/.cabal
以下のpackage.conf.d
の2つに分かれてパッケージリストが表示されますが、前者がシステム用のパッケージ、後者がユーザのインストールしたパッケージのようです。
なお、Cabalを用いて
$ cabal exec ghc-pkg list
とするとsandboxにインストールしたパッケージも一覧することができます。
check
$ ghc-pkg check
とすると、依存関係の壊れたパッケージを一覧することができます。
field
$ ghc-pkg field <パッケージ名> <フィールド名>
とすると、<パッケージ名>
に指定したパッケージの.conf
ファイルの<フィールド名>
に指定したフィールドの値を表示できます。
これを用いて
$ ghc-pkg field <パッケージ名> exposed-modules
とすれば、指定したパッケージで提供されるモジュールの一覧を表示できます。
unregister
$ ghc-pkg unregister <パッケージ名>
とすると、指定したパッケージをアンインストールすることができます。
おわりに
これらを知っておくだけで、かなりHaskellでの開発が楽しくなるかと思います。
というかたのしい。