haskell - 型クラスによる関数型シグネチャのクリーンアップ

haskell typeclass

次のような関数シグネチャを指定します(riakパッケージを使用):

put :: (Storable a, Resolvable a, ToJSON a, FromJSON a) => Connection -> a -> IO ()


次のような型クラスを定義して、関数のシグネチャをクリーンアップするのは悪い考えでしょうか。

class (Storable a, Resolvable a, ToJSON a, FromJSON a) => Persistable a
put :: (Persistable a) => Connection -> a -> IO ()


これは愚かな考えだと聞いてとてもうれしいですが、もしそうなら、その理由を教えていただけますか?

次に、それが悪い考えではないと想定して、UndecidableInstancesを次のように使用することで、キャッチオールインスタンスを定義できます。

instance (Storable a, Resolvable a, ToJSON a, FromJSON a) => Persistable a


ただし、最近、UndecidableInstancesを使用することの短所についていくつかのdiscussion on Haskell-cafeがあり、一般的なコンセンサスは、それを使用することを要求することは設計上の決定を不十分にすることを示しているようです。この場合、正当な使用法ですか、それともPersistableを実装する各タイプクラスに明示的なボイラープレートインスタンスを必要とする方が良いですか?
答え
まず第一に、「定型文を増やす」ことはほとんど決して最良の選択肢ではありません。たとえば、インスタンスを自動生成するためにTHを使用することは、一部の人々がより口当たりが良いと感じる別の代替手段です。

とはいえ、UndecidableInstancesはひどいラップを受けていると思います。本当に、最悪のシナリオは何ですか?コンパイラーを無限ループにしますか?ほんのささいなこと。 H-Mタイプの推論で最悪のケースの複雑さをトリガーする純粋なHaskell 98を数行書くことができ、GHCはギガバイトのメモリを消費するため、GHCの粉砕を停止します。これは、CPUサイクルを燃やすだけの無限ループよりも率直に悪いです。

重要なことは、あなたが賢明なコードを書いている場合、病理学的な振る舞いは起こらないこと、そしてそれを打った場合、一般的に簡単に診断できることです。微妙なバグやインスタンスの選択での奇妙な振る舞いは発生せず、コンパイルするために無効なプログラムを取得することもありません。これは、プログラムで常に扱っている価値レベルでの非終了の可能性と同じです。いくつかの点では、実行時ではなくコンパイル時にエラーが発生するだけなので、それはより良い方法です。

現状では、インスタンスに使用される終了チェックは途方もなく保守的です。確かに正しいケースはたくさんありますが、UndecidableInstancesなしでは記述できません。そして、よりスマートな終了チェッカー、または一般的に明確に安全なケースをサポートする追加機能(Heatsinkが言及したコンテキストエイリアスの提案を参照)があればよいのですが、UndecidableInstancesを使用して必要なものを実装してもまったく害はありませんたった今。最も推奨するのは、エイリアスのみを使用して単一のモジュールにその使用を分離することです。これにより、意図せずに非終了インスタンスを他の場所に書き込むことを心配する必要がなくなります。

記憶が私に役立つならば、これらのポイントのほとんどはhaskell-cafeのOlegによってなされましたが、便利なリンクはありません。しかし、彼はtalk about it on his websiteを行います。



対照的に、OverlappingInstancesはおそらく現在よりも評判が悪いと思います。 :]私の考えでは、UndecidableInstancesよりも概念的にはるかに問題があります。
関連記事

haskell - Haskellの可変ヒープ構造

haskell - Yesodがインストールに失敗する(つまり、テキストパッケージ)

haskell - wxHaskellのラベルが全文を表示できない

haskell - Haskellでのリストの結合

string - Haskellのグリッドからローカルスクエアを返す

haskell - ネットワークパッケージをインストールできません

performance - 素数フィルタの2つの実装のパフォーマンス比較

haskell - Yorgeyらの「unbound」ライブラリを最新のGHC / Haskellプラットフォームにインストールできない

haskell - Showクラスにあるという事実を使用せずに関数を定義する

haskell - Haskellパッケージのバージョン