ライブラリ作成チャート
パッケージを作成 (cabal)
ディレクトリを作成し、cabal initを実行すると対話的に.cabalファイルを作成できる。
code:sh
mkdir my-awesome-package
cd my-awesome-package
cabal init
code::
Please choose version of the Cabal specification to use:
3) 2.2 (+ support for 'common', 'elif', redundant commas, SPDX)
Cabalの最低バーションを指定する。今となっては常識となった^>=記法や、ケツコンマが使える2.4以降がおすすめだ。その後、パッケージの名前、カテゴリや説明などの情報を入力する。 依存パッケージ
依存が少ないのはよいことだが、依存を減らすためだけに車輪を再発明していては元も子もない。パッケージティアリストも参考に依存ライブラリを選択しよう。 モジュールを作成する
やることに応じて、Data 、Control、Systemなどの接頭辞を付けたモジュール名を付ける。
Codec Control Data Database Graphic Network Numeric System Webのいずれかから選ぶのがおすすめだ。
好みの問題だがモジュール名が4語以上(例えばData.Text.Prettyprint.Doc)だと覚えたり入力するのが面倒になってくるので、3語以下に収めたい。
独自性が強い、あるいは守備範囲の広いライブラリならば、オリジナルの接頭辞をつけるのも一興。rioやpipesなどはオリジナルの接頭辞を持つ。 同じパッケージに複数の接頭辞のモジュールを持たせるのは非推奨。どうしてもという場合、そのパッケージに由来すると一目でわかるようにしよう(lensのData.Set.Lensなど)。 モジュール名は他のパッケージのものと被らないようにしたいが、誰も使っていない無名ライブラリなどはあまり気にしなくてよい。
使い手には隠しておきたいようなデータ型や関数なども、Internalモジュールに分けてエクスポートするとハッカーが喜ぶ。特にデータ型のコンストラクタを完全に隠蔽してしまうと拡張性が損なわれるので、特別な理由がない限り公開したい(大切なこと)。 モジュールの中身
基本的には、標準ライブラリ(特にPrelude)と被るような識別子は避けたい。Data.Setのように、qualifiedインポートを前提とする慣習に沿うならこの限りではない。
孤児インスタンスを持たせるのは可能な限り避けたい。どうしてもという場合、Orphans をモジュール名に入れて必要な時のみインポートさせるようにする。 パッケージのバージョニング
シンボル(関数や型など)の削除
インスタンスの追加、削除
マイナーバージョンZは、シンボルやモジュールを追加した時にインクリメントする。Wは、ドキュメントなどの細かい修正に使う程度で、あまり気にしなくてよい。なお、バージョンは4桁より少なくてもよい。
継続的インテグレーション
カジュアルなライブラリなら一つ古いGHC、ティアリストのトップと渡り合うなら二つか三つ前のGHCまでサポートしたい(GHC 8.6が最新なら、GHC 8.2まで)。そんなときはhaskell-ciを使って設定するのがおすすめだ。cabalファイルにTested-With: GHC ==8.6.4 || ==8.4.4 || ==8.2.2のように記述し、haskell-ciを実行すると.travis.ymlが生成される。 code:sh
cabal new-install haskell-ci
haskell-ci sugoi-package.cabal --output .travis.yml
TBD: Circle CIの設定
Hackageのアカウントを作る
準備が整ったらいざHackageにアップロード…と、その前にアカウントの作成が必要である。ユーザー名は本名でなくてもいいが、なんでもいいという訳ではなく、人名らしい名前をつけることが推奨されている。
配布用アーカイブを作成する
code:sh
$ cabal v2-sdist
Wrote tarball sdist to
/Users/monazaemon/sugoi-package/dist-newstyle/sdist/sugoi-package-0.tar.gz
アップロードする
code:sh
$ cabal upload dist-newstyle/sdist/sugoi-package-0.tar.gz --publish