昨日、Stackと呼ばれる新しいHaskellツールについて学びました。最初の赤面では、それはカバルとほとんど同じ仕事をしているように見えます。では、それらの違いは何ですか?StackはCabalの代替品ですか?どの場合、Cabalの代わりにStackを使用する必要がありますか?StackalがCabalでできないことは何ですか?
昨日、Stackと呼ばれる新しいHaskellツールについて学びました。最初の赤面では、それはカバルとほとんど同じ仕事をしているように見えます。では、それらの違いは何ですか?StackはCabalの代替品ですか?どの場合、Cabalの代わりにStackを使用する必要がありますか?StackalがCabalでできないことは何ですか?
回答:
StackはCabalの代替品ですか?
はいといいえ。
どの場合、Cabalの代わりにStackを使用する必要がありますか?StackalがCabalでできないことは何ですか?
Stackは、デフォルトでキュレートされたスタックパッケージを使用します。そのため、すべての依存関係が一緒に構築され、バージョンの競合の問題(Haskellエクスペリエンスでは一般的だった当時は、「カバル地獄」として知られていました)を回避することがわかっています。Cabalの最近のバージョンでも、競合を防ぐための対策が講じられています。それでも、リポジトリから何がプルされるかが正確にわかる再現可能なビルド構成をセットアップすることは、Stackを使用する方が簡単です。非Stackageパッケージを使用するためのプロビジョニングもあるので、パッケージがStackageスナップショットに存在しない場合でも移動することをお勧めします。
個人的に、私はスタックが好きで、すべてのHaskell開発者にそれを使用することをお勧めします。彼らの開発は速いです。そして、それはずっと良いUXを持っています。そして、StackがCabalをまだ提供していないものがあります:
stack build --fast --file-watch
。存在するローカルファイルを変更すると、これは自動的に再構築されます。--pedantic
オプションと一緒にそれを使用することは、私にとって契約上の決断です。違いを説明する素晴らしいブログ投稿があります:なぜStackはCabalではないのですか?Cabalは、そのポストからの数年間で、そこで議論された問題のいくつかを克服するために進化しましたが、Stackの背後にある設計目標と哲学の議論は依然として関連しています。
以下では、比較される2つのツールをcabal-installとstackと呼びます。特に、両方のツールで使用される共通のインフラストラクチャであるCabalライブラリとの混乱を避けるために、cabal-installを使用します。
大まかに言えば、cabal-installとstackはCabalのフロントエンドと言えます。どちらのツールでも、単一システムの範囲内で依存関係のセットが互いに競合する可能性があるHaskellプロジェクトを構築できます。それらの主な違いは、彼らがこの目標にどのように対処するかにあります。
デフォルトでは、cabal-installは、プロジェクトをビルドするように求められると、その.cabal
ファイルで指定された依存関係を調べ、依存関係ソルバーを使用して、それを満たす一連のパッケージとパッケージバージョンを見つけます。このセットはHackage全体から抜粋したものです。過去と現在のすべてのパッケージとすべてのバージョンです。実行可能なビルドプランが見つかると、選択したバージョンの依存関係がインストールされ、のどこかのデータベースにインデックスが作成されます~/.cabal
。インストールされたパッケージにバージョン(およびその他の関連する構成オプション)に従ってインデックスを付けることで、依存関係間のバージョンの競合を回避できるため、異なるプロジェクトが互いに依存することなく、必要な依存関係のバージョンを取得できます。この配置はcabal-installドキュメントは、「Nixスタイルのローカルビルド」を意味します。
プロジェクトをビルドするように求められると、スタックはHackageに行くのではなく、のresolver
フィールドを調べますstack.yaml
。デフォルトのワークフローでは、そのフィールドはStackage スナップショットを指定します。これは、相互に互換性があることがわかっている修正されたバージョンのHackageパッケージのサブセットです。スタックは、その後に指定された依存関係を満たすためにしようとし.cabal
たファイル(または、おそらくファイルのスナップショットで提供されたもののみ使用して-別のフォーマット、同じ役割を)。各スナップショットからインストールされたパッケージは、互いに干渉しない別々のデータベースに登録されます。project.yaml
スタック構成は、ビルド構成を指定する際に、セットアップの柔軟性をわかりやすくする代わりに使用すると言えます。特に、プロジェクトでLTS 15.3スナップショットを使用していることがわかっている場合は、Stackageページに移動すると、一見すると、依存関係スタックのバージョンがStackageから取得される可能性があることがわかります。とはいえ、どちらのツールも基本的なワークフローを超える機能を提供するため、概して、それぞれが他の機能と同じことをすべて実行できます(ただし、あまり便利ではない方法で)。たとえば、既知の適切なビルド構成の正確なバージョンをフリーズし、cabal-install を使用して古い状態のHackageで依存関係を解決する方法があります。、およびStackの使用中に、Stackage以外の依存関係を要求したり、スナップショットパッケージのバージョンを上書きしたりすることができます。
最後に、cabal-installとstackのもう1つの違い、この概要で言及する価値があるほど大きく、stackは、自動GHCインストール管理やDocker統合などの機能を備えた完全なビルド環境を提供することを目的としていることです。対照的に、cabal-installはエコシステムの他の部分に直交することを意図しているため、この種の機能を提供しようとはしていません(特に、GHCバージョンはLinuxディストリビューションを介してインストールおよび管理する必要があります)パッケージ、WindowsのHaskellプラットフォームコア、またはghcupツール)。
FAQから収集できることから、StackはCabalライブラリを使用していますが、cabal.exe
バイナリ(より正確にはcabal-installとして知られています)を使用していないようです。プロジェクトの目的は、自動サンドボックス化と依存関係の地獄の回避であるようです。
言い換えると、同じCabalパッケージ構造を使用し、これを管理するための異なるフロントエンドを提供するだけです。(おもう!)
cabal
、彼らのソースコードも使用しているようですdocker
。彼らがまだそれを使っているかどうかはわかりませんが。
cabal-install
て使用します-ある時点でcabal-installへのバックインテグレーションがあり、コミュニティを分割する可能性があるため、コミュニティはこれが良いことかどうか確信がありません)