Utilizzando GHC RULES
pragma, è possibile specializzare una funzione polimorfica per tipi specifici. Esempio dal rapporto Haskell:Regola di riscrittura GHC specializzata in una funzione per una classe di tipo
genericLookup :: Ord a => Table a b -> a -> b
intLookup :: Table Int b -> Int -> b
{-# RULES "genericLookup/Int" genericLookup = intLookup #-}
Ciò renderebbe GHC utilizzare intLookup
su una tabella di interi indicizzata e la versione generica in caso contrario, in cui intLookup
sarebbe probabilmente più efficiente.
vorrei realizzare qualcosa di simile, utilizzando funzioni come le seguenti (leggermente semplificate) quelli:
lookup :: Eq a => [(a, b)] -> a -> b
lookupOrd :: Ord a => [(a, b)] -> a -> b
dove lookupOrd
crea un Map
dalla lista di input e quindi utilizza Map.lookup
, che richiede che a
essere un membro di Ord
.
Ora vorrei dire che GHC lookupOrd
dovrebbe essere usato al posto di lookup
ogni volta a
è davvero un membro della classe Ord
tipo. La seguente regola, tuttavia, non TYPECHECK:
{-# RULES "lookup/Ord" lookup = lookupOrd #-}
GHC (giustamente) si lamenta che non si può dedurre (Ord a)
dal contesto (Eq a)
. Esiste una regola di riscrittura che mi consenta di eseguire questo tipo di specializzazione basata sulla classe di tipo?
Questo è praticamente il vecchio problema [open-world] (http://stackoverflow.com/a/1072523/745903): stai cercando di prendere una decisione in base alla presenza o meno di un tipo tipo di classe. _Ma Haskell non ha idea di ** non ** essere in una classe tipo! Si presume sempre che qualsiasi tipo possa essere in qualsiasi classe (anche se non è stata ancora trovata alcuna istanza di questo tipo, qualcuno potrebbe comunque aggiungerla in seguito). – leftaroundabout
@leftaroundabout che il problema non è troppo grave; potrebbe essere immaginato un approccio best-effort all'applicazione di tale regola (se GHC lo sosterrebbe in primo luogo). –