僕ののHaskell開発環境を紹介する

趣旨

 僕は僕のHaskell開発環境を使っているのだけど(それはそう)、常々これはなかなか便利だと思っている。

加え、Haskellの開発環境の導入方法がよくわからないという声をとても多く聞く。

 幸い、前提となるHaskell開発ツールキットの導入については、こちらにわかりやすい記事がある。

 ここでは、これらのツールキットをどのようにうまく使うか ……例えば、TDDに適したテキストエディタは? 今表示しているこの関数の型ってどうやったらわかる? というのを、「僕はこうしているよ」という様にまとめておく。

 また、「こっちの方がいいんじゃ?」というのがあれば、教えてもらいたい。 あと、皆も自分のやつを晒すといいと思う。

 そういえばこういうのも開催されているらしい。

本的な構成

  • CLI
    • シェル(bashでもzshでもなんでも)
      • and commands
    • Vim or NeoVim
      • and plugins

テキストエディタ

 まず開発者が一番気になるのがテキストエディタだと思う。 また、IDEを使うかどうか、という話にもなる。

 僕はVimを常用していて、全ての言語をVimで書いているので (Javaも、Kotlinも、そしてC#も)、 やはりVimを使う。

 この前までNeoVimを使っていたので、NeoVimでも行けると思う。

hasktags + haskdogsを使う

Vimでの設定

 Vimにはctagsという、 関数や型の情報を集収したファイルを参照し、 関数や型が記述されている実際のファイル位置に飛ぶことができる 機能がある。

 tagファイルは通常ctagsコマンドで生成できる。

 僕はそれを読み込むために、.vimrc'tags'を以下のように設定している。

let &tags = join([
\    'tags',
\    '.git/tags',
\    '../.git/tags',
\    '../../.git/tags',
\    '../../../.git/tags',
\    '../../../../.git/tags'
\], ',')

 これは./tagsか、もしくは.git/tags, ../.git/tags, ...にあるそのtagsを読み込む。

hasktags

 Haskellに特化したctagsコマンド亜種として、 hasktagsコマンドがある。

 これは、今我々が作っているプロジェクトにある各.hsファイルに記述された 全ての関数を扱うことができる。

hasktags-image

 以下のシェルコマンドでインストールできる。

$ stack install hasktags

 僕はこんなaliasをシェルに定義して使っている。

alias hasktags-casual='hasktags . --ignore-close-implementation --tags-absolute --ctags -f'
$ haskdogs .git/tags
(.git/tagsに、各.hsファイルの関数の羅列が出力される)

haskdogs

 上でhasktagsの使い方を紹介したものの、まあ普通はこれだけ使っていればいい。

 haskdogsは……hasktagsを使って、 自プロジェクトの依存しているパッケージのtagsも出力してしまおう、というもの。

 例えば、自プロジェクトがeasy-fileパッケージのdoesFileExist関数を使っている時に haskdogsを実行すると、haskdogsはghc-pkgコマンドを使って easy-fileのソースを$HOME/.haskdogs以下に落としてきて、 そこを参照するtagsを生成する。

 また、生成されたtagsには自プロジェクトの各関数も含まれるので、 プロジェクトに関係する、 ほぼ全ての関数と型をエディタに表示できる!

haskdogs-image

 以下のシェルコマンドでインストールできる。

$ stack install haskdogs

unite-tag

 tagsファイルをUniteで開くのに使用する。 関数名、型名でtagsファイル内を検索することができる。

 例えば、現在開いているバッファに引きたい関数名がなくとも、 これで検索することができる。 (普段は名前の上にカーソルを載せて、<C-]>キーでtagsの先にジャンプできる)

aref-web.vimで関数名や型を調べる

 haskdogsとVimのtagジャンプ機能そしてunite-tagで、 自プロジェクトに関係するほぼ全ての関数と型を引くことができた。

 これの唯一できないことは、自プロジェクトに関係ないものを引くことだ。 これはVimで、Web上のStackage検索を使うことで実現する。

 Web辞書(例えばWeblio)をVimで引くためのプラグインとして、aref-web.vimがある。

 これは僕が作ったものなのだけど、 これのデバッグはずっとStackageを用いて行っていたこともあり、 Stackageについては十分に実用できるレベルになっていると思う。

aref-image

(まあ…… 誰も注目してくれていないみたいだし、 僕もStackage検索を行うために作ったものなので、 他のサイトについてはまだβという感じ)

StackageのWebサイトは、 Haskellの関数とライブラリの検索に対応しており

例えば

  • a -> aの型を持つあの関数の名前ってなんだっけ?
  • id関数の型ってなんだっけ?
  • doesFileExist関数ってどのライブラリが提供してるんだっけ?
  • m a -> aみたいな型を持つ関数ってないかな?

というシチュエーションに対して対応することができる。

 余談だけど、僕はこれで英和辞書を使ってたりもするので便利(ステマ)。

snowtify

筆者プロフィール

my-latest-logo

aiya000(あいや)

せつラボ 〜圏論の基本〜」 「せつラボ2~雲と天使と関手圏~」 「矢澤にこ先輩といっしょに代数!」を書いています!

強い静的型付けとテストを用いて、バグを防ぐのが好き。Haskell・TypeScript。