GHC RULES
pragmaを使用すると、特定のタイプの多型関数を特殊化することができます。 Haskellのレポートからの例:タイプクラスの関数を特化したGHC書き換えルール
genericLookup :: Ord a => Table a b -> a -> b
intLookup :: Table Int b -> Int -> b
{-# RULES "genericLookup/Int" genericLookup = intLookup #-}
これは、GHCはintLookup
はおそらく、より効率的である整数インデックステーブルとジェネリックそうでない場合は、上のintLookup
を使用するだろう。
Iは、以下の(わずかに単純化された)もののような関数を使用して、同様の何かを達成したい:a
であることを必要とlookupOrd
が入力リストからMap
を作成し、Map.lookup
を使用
lookup :: Eq a => [(a, b)] -> a -> b
lookupOrd :: Ord a => [(a, b)] -> a -> b
をOrd
のメンバー。
今私はa
が実際Ord
型クラスのメンバーである時はいつでもlookupOrd
がlookup
の代わりに使用する必要があることをGHCに伝えたいと思います。次のルールは、しかし、です。TypeCheckしません:
{-# RULES "lookup/Ord" lookup = lookupOrd #-}
GHC(当然)それは文脈(Eq a)
から(Ord a)
を推測することができないと文句を言い。このような種類のクラスベースの特殊化を実行するためのリライトルールはありますか?
これは、古い[オープンワールドの問題](http://stackoverflow.com/a/1072523/745903)にほとんど影響しています。タイプがいくつかのタイプにあるかどうかに基づいて判断しようとしていますタイプクラス。 _しかし、Haskellは** class **の中に**ないという概念はない!どんな型でも(たとえそのようなインスタンスがまだ出現していなくても、誰かがそれを後で追加しても)どんな型であってもよいと常に考えられます。 – leftaroundabout
@leftaroundについてこの問題はそれほど深刻ではありません。そのようなルールを適用するためのベスト・エフォート・アプローチを想像することができます(GHCが最初にそれをサポートする場合)。 –