# himari [![CI](https://github.com/ncaq/himari/actions/workflows/push.yml/badge.svg)](https://github.com/ncaq/himari/actions/workflows/push.yml) [![License](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](https://github.com/ncaq/himari/blob/master/LICENSE) [![Haskell](https://img.shields.io/badge/language-Haskell-5D4F85.svg)](https://www.haskell.org/) [![Hackage](https://img.shields.io/hackage/v/himari.svg?logo=haskell)](https://hackage.haskell.org/package/himari) [![Haddock](https://img.shields.io/badge/docs-Haddock-purple.svg)](https://hackage.haskell.org/package/himari/docs/Himari.html) ![Linux](https://img.shields.io/badge/linux-x86__64%20|%20ARM64-brightgreen?logo=linux&logoColor=white) ![macOS](https://img.shields.io/badge/macOS-x86__64%20|%20ARM64-brightgreen?logo=apple&logoColor=white) ![Windows](https://img.shields.io/badge/windows-x86__64-brightgreen?logo=windows&logoColor=white) A standard library for Haskell to replace rio ## 注意 > [!IMPORTANT] > himariはrioとは完全に同じように使えるわけではありません。 > ここで主な注意点を挙げます。 ### 重大なランタイムの非互換性 #### ログの出力先の変更 rioは基本的に標準出力にログを出力しますが、 himariはデフォルトのガイドラインに従うと標準エラー出力にログを出力します。 ログは標準エラー出力に出すべきだと考えているためです。 変更したい時は出力先を`stderr`から`stdout`などに変更することで簡単に変更可能です。 ### 部分関数への対処方法の違い rioは部分関数を独自のモジュールでexportして提供していますが、 himariはそのままオリジナルのモジュールを使ってもらいます。 よってhimariは部分関数を除去していません。 なのでhimariはhlintのルールで警告を出すことで対処しています。 プロジェクトルートにある[.hlint.yaml](./.hlint.yaml)ファイルを、 以下のような方法であなたのプロジェクトにコピーしてください。 ```console curl -L 'https://raw.githubusercontent.com/ncaq/himari/master/.hlint.yaml' -o '.hlint.yaml' ``` ## 背景 私は、 [commercialhaskell/rio: A standard library for Haskell](https://github.com/commercialhaskell/rio) の思想が好みで長く使っています。 しかしrioの好みではない点もいくつかあります。 単純に質の問題であれば私がコントリビュートすれば良いのですが、 非互換な選択である部分が多いため、 それは受け入れられないだろうと考えて、 rioに似たライブラリであるhimariを作成することにしました。 ## 目標 ### 依存関係が大きくなることを恐れない rioは依存関係を小さくしようと考えているのか、 [lens: Lenses, Folds and Traversals](https://hackage.haskell.org/package/lens) ではなく、 [microlens: A tiny lens library with no dependencies](https://hackage.haskell.org/package/microlens) を採用しています。 しかし実際のライブラリでは本家のlensに依存していることも多く、 結局使おうとしてコンフリクトすることが多いです。 Haskellは静的にビルドする言語なので、 依存関係が多いことはあまり怖くありません。 使うとは限らない依存関係もドシドシimportしてしまいます。 バージョンごとの依存関係の解決が大変なのはNixなどのパッケージマネージャのレイヤーで解決することにします。 ### なるべく一行で済ませたい himariは基本的には以下の一行で代替Preludeを提供することを目指します。 ```haskell import Himari ``` 色々と書くのは面倒ですからね。 これで衝突しない範囲はたくさんimportしてしまいます。 同じシンボル名をexportしていて衝突してしまうものは仕方がないのでqualified importを使ってもらいます。 ### なるべく独自のシンボルを定義しない himariはrioで言う`RIO.Text`のような独自のシンボルを定義することをなるべく避けます。 LLMのコーディングエージェントに独自のシンボルを使うことを守ってもらうのが難しいからです。 しばしばオリジナルのシンボルを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が警告を出してくれます。 ## Nix このプロジェクトは[haskell.nix](https://input-output-hk.github.io/haskell.nix/)を使用しています。 ### `nix flake show`が失敗する場合 haskell.nixはIFD(Import From Derivation)を使用するため、 複数システムをサポートするflakeで`nix flake show`を実行すると、 異なるシステム向けのビルドを評価しようとして失敗することがあります。 これはhaskell.nixの既知の制限であり、 現在のところ完全な回避策はありません。