使用GHC RULES
pragma,可以爲特定類型專門化多態函數。從哈斯克爾報告舉例:GHC重寫規則專用於類型類的函數
genericLookup :: Ord a => Table a b -> a -> b
intLookup :: Table Int b -> Int -> b
{-# RULES "genericLookup/Int" genericLookup = intLookup #-}
這將使GHC上一個整數索引表和仿製藥,否則其中intLookup
很可能是更有效地利用intLookup
。
我想完成類似的東西,使用如下(略微簡化的)那些功能:
lookup :: Eq a => [(a, b)] -> a -> b
lookupOrd :: Ord a => [(a, b)] -> a -> b
其中lookupOrd
創建從輸入列表中Map
,然後使用Map.lookup
,這要求a
是Ord
的成員。
現在我想告訴GHC,lookupOrd
應該用來代替lookup
,只要a
確實是Ord
類型類的成員。下面的規則,但是,不進行類型檢查:
{-# RULES "lookup/Ord" lookup = lookupOrd #-}
GHC(理所當然)抱怨說,它不能從上下文推斷(Eq a)
(Ord a)
。是否有一個重寫規則可以讓我執行這種基於類的專業化?
這幾乎是運行到舊的[開放世界的問題](http://stackoverflow.com/a/1072523/745903):你試圖根據是否在某種類型作出決定類型的類。 _但Haskell沒有** not **的概念在類型class_中!總是假設任何類型都可能在任何類中(即使沒有遇到過這樣的實例,有人可能會在後面添加它)。 – leftaroundabout
@leftaroundabout該問題不是太嚴重;可以想象應用這種規則的最佳方法(如果GHC首先支持它)。 –