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


Modified text is an extract of the original Stack Overflow Documentation
Licenciado bajo CC BY-SA 3.0
No afiliado a Stack Overflow