Haskell Language
Reglas de reescritura (GHC)
Buscar..
Usando reglas de reescritura en funciones sobrecargadas
En esta pregunta , @Viclib preguntó sobre el uso de reglas de reescritura para explotar las leyes de clase de tipos y eliminar algunas llamadas a funciones sobrecargadas:
Cuidado con la siguiente clase:
class ListIsomorphic l where toList :: l a -> [a] fromList :: [a] -> l a
También exijo que
toList . fromList == id
. ¿Cómo escribo las reglas de reescritura para decirle a GHC que haga esa sustitución?
Este es un caso de uso un tanto complicado para el mecanismo de reglas de reescritura de GHC, porque las funciones sobrecargadas se reescriben en sus métodos de instancia específicos mediante reglas que están creadas implícitamente detrás de escena por GHC (por lo tanto, algo como fromList :: Seq a -> [a]
sería reescrito en Seq$fromList
etc.).
Sin embargo, al reescribir primero a toList
y fromList
a métodos no tipográficos no tipográficos, podemos protegerlos de una reescritura prematura y preservarlos hasta que la regla para la composición pueda activarse:
{-# RULES
"protect toList" toList = toList';
"protect fromList" fromList = fromList';
"fromList/toList" forall x . fromList' (toList' x) = x; #-}
{-# NOINLINE [0] fromList' #-}
fromList' :: (ListIsomorphic l) => [a] -> l a
fromList' = fromList
{-# NOINLINE [0] toList' #-}
toList' :: (ListIsomorphic l) => l a -> [a]
toList' = toList