A standard library for Haskell to replace rio
このプロジェクトは、 commercialhaskell/rio: A standard library for Haskell の思想を踏襲しつつ、 よりスムーズな開発が出来ることを目指した改良ライブラリです。
私はrioの思想が好みで長く使っています。
しかしrioの好みではない点もいくつかあります。 単純に質の問題であれば私がコントリビュートすれば良いのですが、 非互換な選択である部分が多いため、 それは受け入れられないだろうと考えて、 rioに似たライブラリであるhimariを作成することにしました。
例えばrioは依存関係を小さくしようと考えているのか、 lensではなく、 microlensを採用しています。
しかし実際のライブラリでは本家のlensに依存していることも多いです。 開発でも実際のlensを使いたいです。 その結果コンフリクトすることが多発します。
Haskellは静的にビルドする言語なので、 依存関係が多いことはあまり怖くありません。
ビルドした時に使わないデッドコードはコンパイラが勝手に消してくれます。
他にも使うとは限らない依存関係もドシドシimportしてしまいます。
バージョンごとの依存関係の解決が大変なのは、 Nixなどのパッケージマネージャのレイヤーで解決することにします。
himariは基本的には以下の一行で代替Preludeを提供することを目指します。
import Himari色々と書くのは面倒なので。 衝突しない範囲で大量にimportしてしまいます。
同じシンボル名をexportしていて衝突してしまうものは仕方がないので、 qualified importを使ってもらいます。
himariはrioで言うRIO.Textのような独自のシンボルを定義することをなるべく避けます。
開発メンバーやコーディングエージェントに独自のシンボルを使うことを守ってもらうのが難しいからです。
しばしばオリジナルのシンボルをimportしてしまい、
コードレビューなどで手戻りが発生します。
ただしHimari.Preludeのサブモジュールは存在します。
Himari.Prelude.Aesonなどのシンボルです。
これはHaddockの制限により、
hidingを使ったre-exportはシンボルが全て展開されてしまうからです。
シンボルの展開が発生するとドキュメントが肥大化してしまいます。
サブモジュールでhidingを隠蔽することで、
Himari.Preludeのドキュメントをコンパクトに保っています。
これらのサブモジュールはHimari.Preludeから自動的にre-exportされるため、
rioのRIO.Textのように個別にimportする必要はありません。
ユーザから見ると直接扱う必要は基本的にないということです。
万が一誤ってサブモジュールを直接importした場合でも、
Himari.Preludeと重複importすることになり、
GHCが警告を出してくれるので、
気が付きやすいです。
himariを使うプロジェクトでは、 以下の設定ファイルをコピーすることを強く推奨します。
himariは部分関数を除去する代わりに、
hlintで警告を出すことで対処しています。
プロジェクトルートにある.hlint.yamlファイルをコピーしてください。
既存のhlint.yamlがある場合はマージしてください。
curl -L 'https://raw.githubusercontent.com/ncaq/himari/master/.hlint.yaml' -o '.hlint.yaml'fourmoluはHaskellのフォーマッタです。 fourmoluは演算子の優先順位(fixity)を正しく解決するために、 カスタムPreludeがどのモジュールをre-exportしているかを知る必要があります。
プロジェクトルートにある、
fourmolu.yamlファイルの、
reexportsセクションをコピーしてください。
既存のfourmolu.yamlがある場合はreexportsセクションをマージしてください。
curl -L 'https://raw.githubusercontent.com/ncaq/himari/master/fourmolu.yaml' -o 'fourmolu.yaml'Note
fourmolu.yamlにはhimari固有のフォーマット設定(indentation, column-limitなど)も含まれています。 素朴な設定ですが、プロジェクトに合わせて適宜変更してください。
Important
himariはrioとは完全に同じように使えるわけではありません。 ここで主な注意点を挙げます。
rioは基本的に標準出力にログを出力しますが、 himariはデフォルトのセットアップ手順に従うと標準エラー出力にログを出力します。
ログは標準エラー出力に出すべきだと考えているためです。
変更したい時は出力先をstderrからstdoutなどに変更することで簡単に変更可能です。
rioは部分関数を独自のモジュールでexportして提供していますが、 himariはそのままオリジナルのモジュールを使う方針です。
よってhimariは部分関数を除去していません。
なのでhimariはhlintのルールで警告を出すことで対処しています。 詳細はセットアップを参照してください。
このプロジェクトは開発環境として、 haskell.nix を使用しています。
あくまで開発環境として利用しているだけなので、 himariを使うのにnixを利用する必要はありません。
haskell.nixはIFD(Import From Derivation)を使用するため、
複数システムをサポートするflakeでnix flake showを実行すると、
異なるシステム向けのビルドを評価しようとして失敗することがあります。
これはhaskell.nixの既知の制限であり、 現在のところ完全な回避策はありません。