• 作成:

これからのHaskellプロジェクトではcabalではなくpackage.yaml(hpack)を使いましょう

sol/hpack: hpack: An alternative format for Haskell packages

hpackとは

hpackとは, cabalファイルを生成してくれるツールです.

package.yamlファイルからcabalファイルを生成します.

JavaScriptに対するAltJSのようなものです.

hpackは何が良いのか

yamlである

hpackのフォーマットであるpackage.yamlはyamlフォーマットです.

独自のフォーマットを採用しているcabalとは違い, 様々なエディタが普通に対応しており, プログラムからも扱いやすくなっています.

ボイラープレートを自動生成してくれる

default-language: Haskell2010のような現代では当たり前の記述を自動生成してくれるため, わざわざ書かなくて済むようになります.

exposed-modulesを自動生成してくれる

cabalではexportするモジュールを全てlibraryexposed-modulesに書かなくてはいけませんでした.

hpackでは

library:
  source-dirs: src

のように書くだけで, src以下のモジュールを自動的にcabalに書いてくれます.

長い記述が不要になり, モジュールの名前が変わっても自動的に変更されるので, 楽です.

other-modulesを自動生成してくれる

hspecなどを使うとtest-suiteother-modulesにたくさんSpecモジュールを書く必要がありますが, hpackを使うとこれも自動生成してくれます.楽です.

build-dependsの共通部分をまとめられる

cabalではlibrarytest-suiteなどのbuild-dependsに共通部分があっても, それらを全てコピペして並べなければいけませんでした.

面倒くさいですし, 共通の依存が並んでいるとtest-suiteだけが要求するライブラリがわかりにくくなります.

hpackではトップレベルの場所にdependencies:を書いておくと, cabalファイルではlibraryexecutablestest-suiteもこの依存を継承するようになります.

後は以下のようにtests部分だけにtestだけが要求する依存をわかりやすく記述することが出来ます.

tests:
  test:
    main: Spec.hs
    source-dirs: test
    dependencies:
    - foo-application
    - hspec
    - yesod-test

githubのURLからhomepage, bug-reports, source-repositoryを自動生成してくれる

github: user/repo

のようにgithubのリポジトリを指定すると, 自動的にcabalにhomepage, bug-reports, source-repositoryを記述してくれます. 楽です.

変数が使える

cabalでは変数が使えなかったため, 共通する記述もコピペするしか書く方法がありませんでしたが, hpackでは変数が使えるため, 例えば共通するghcオプションなどを変数にまとめ, それぞれの場所で展開することが出来ます.

hpackを使うには

現在のstackはhpackにデフォルト対応しているため, package.yamlが存在するディレクトリでstack buildすれば自動的にcabalファイルを作成してビルドしてくれます.

cabalファイルは自動生成されるようになるため, cabalファイルは.gitignoreで除外しておくようにしましょう.

新規プロジェクトの場合

stack new foo simple-hpackのようにすると, hpackでプロジェクト設定が生成されます.

また, yesodもhpackを採用するようになったため, stack new foo yesod-postgresなどをしてもhpackが使われるようになります.

既存プロジェクトの移行

hpack-convert: Convert Cabal manifests into hpack's package.yamlsを使えばcabalファイルから簡単にpackage.yamlを作成することが出来ます.

このツールは結構賢く, 共通部分を自動的にまとめたpackage.yamlが生成されます.