なぜあなたがこれをしたいのか理解していますが、残念ながら、Haskellクラスがあなたの言うように「オープン」に見えるのは幻想にすぎないかもしれません。多くの人は、これを行う可能性は、以下で説明する理由から、Haskell仕様のバグであると感じています。とにかく、クラスが宣言されているモジュールまたは型が宣言されているモジュールのいずれかで宣言する必要があるインスタンスに本当に適切でない場合、それはおそらく、newtype
または他のラッパーを使用する必要があることを示していますあなたのタイプの周り。
孤立したインスタンスを回避する必要がある理由は、コンパイラの利便性よりもはるかに深くなります。他の回答からわかるように、このトピックはかなり物議を醸しています。議論のバランスをとるために、孤立したインスタンスを作成してはならないという観点を説明します。これは、経験豊富なHaskellerの多数意見だと思います。私自身の意見は途中ですが、最後に説明します。
この問題は、同じクラスとタイプに対して複数のインスタンス宣言が存在する場合、標準のHaskellにはどちらを使用するかを指定するメカニズムがないという事実に起因します。むしろ、プログラムはコンパイラーによって拒否されます。
その最も単純な効果は、他の誰かがモジュールの依存関係から遠く離れて行った変更のために、突然コンパイルを停止する完全に機能するプログラムを持つことができるということです。
さらに悪いことに、遠方の変更が原因で、動作中のプログラムが実行時にクラッシュし始める可能性があります。特定のインスタンス宣言からのものであると想定しているメソッドを使用している可能性があり、プログラムが不可解にクラッシュし始めるのに十分なだけ異なる別のインスタンスにサイレントに置き換えられる可能性があります。
これらの問題が発生しないことを保証したい人は、誰かが、どこでも、特定のタイプの特定のクラスのインスタンスを宣言したことがある場合、作成されたプログラムで他のインスタンスを再度宣言してはならないという規則に従う必要があります誰でも。もちろん、を使用newtype
して新しいインスタンスを宣言する回避策はありますが、それは常に少なくとも小さな不便であり、時には大きな不便です。したがって、この意味で、孤立したインスタンスを意図的に作成する人は、かなり失礼です。
では、この問題について何をすべきでしょうか?アンチオーファンインスタンスキャンプは、GHC警告はバグであり、オーファンインスタンスを宣言する試みを拒否するエラーである必要があると述べています。その間、私たちは自己規律を行使し、絶対にそれらを避けなければなりません。
あなたが見てきたように、それらの潜在的な問題についてそれほど心配していない人たちがいます。彼らは実際に、あなたが示唆するように、関心の分離のためのツールとして孤立したインスタンスの使用を奨励し、問題がないことをケースバイケースで確認する必要があると言っています。私は、他の人々の孤児の実例によって、この態度があまりにも騎士的であると確信するのに十分な回数不便を感じてきました。
正しい解決策は、インスタンスのインポートを制御するHaskellのインポートメカニズムに拡張機能を追加することだと思います。それは問題を完全に解決するわけではありませんが、世界にすでに存在する孤立したインスタンスからの損傷からプログラムを保護するのに役立つでしょう。そして、時間が経つにつれて、特定の限られたケースでは、おそらく孤立したインスタンスはそれほど悪くないかもしれないと確信するかもしれません。(そして、その誘惑が、孤児対策キャンプの一部が私の提案に反対している理由です。)
これらすべてからの私の結論は、少なくとも当面は、他の理由がない場合は他の人に配慮するために、孤立したインスタンスを宣言することは避けることを強くお勧めします。を使用しnewtype
ます。