2012-03-21 15 views
8

Por lo que puedo decir, no creo que suponga ninguna diferencia que id1 e id2 sean de una clase de tipo y id1 'e id2' ​​no. Estoy ejecutando "ghc Rewrite" con la última plataforma Haskell (tanto con GHC versión 7.0.4 como ahora 7.4.1 también), y espero que también se active.Reescribir las reglas que no se activan para las reglas que coinciden con los métodos de instancia múltiple

$ ghc Rewrite 
[1 of 1] Compiling RewriteProblems (Rewrite.hs, Rewrite.o) 
Rule fired: rewrite/ez' 
Rule fired: rewrite/to1' 
Rule fired: rewrite/ez 
Rule fired: rewrite/ez 
Rule fired: Class op id2 
Rule fired: Class op id2 

el ejemplo:

{-# OPTIONS_GHC -O -ddump-rule-firings #-} 
module RewriteProblems where 

{-# RULES 
"rewrite/ez" forall a. id1 a = RDUnit 
"rewrite/to1" forall a. id2 (id2 a) = id1 a 
"rewrite/ez'" forall a. id1' a = RDUnit 
"rewrite/to1'" forall a. id2' (id2' a) = id1 a 
    #-} 

class Ider a where 
    id1 :: a -> a 
    id2 :: a -> a 

data RewriteD = RDUnit 

instance Ider RewriteD where 
    {-# INLINE[1] id1 #-} 
    {-# INLINE[1] id2 #-} 
    id1 a = RDUnit 
    id2 a = RDUnit 

testThing1 :: RewriteD 
testThing1 = id1 RDUnit 

testThing2 :: RewriteD 
testThing2 = id2 (id2 RDUnit) 

testThing1' :: RewriteD 
testThing1' = id1' RDUnit 

testThing2' :: RewriteD 
testThing2' = id2' (id2' RDUnit) 

{-# INLINE[1] id1' #-} 
{-# INLINE[1] id2' #-} 
id1' :: RewriteD -> RewriteD 
id2' :: RewriteD -> RewriteD 
id1' a = RDUnit 
id2' a = RDUnit 

Respuesta

5

(varias ediciones realizadas a lo largo post con información actualizada)

En su salida, observe las líneas Rule fired: Class op id2. Estas son reglas creadas automáticamente por GHC para las instancias de clase de tipo. Esta regla se activa primero, por lo que su propia regla nunca tendrá la oportunidad de coincidir. Si compila con "-ddump-simpl-iterations", puede verificar que la regla de clase Opción se active en la primera fase, después de lo cual su regla "to1" nunca coincidirá.

Aquí hay un poco de una solución. Primero comente testThing1, testThing1' y testThing2', por lo que solo se compila testThing2. Esta es la única función donde "rewrite/to1" puede dispararse, por lo que aísla el caso de prueba que está mirando. A continuación añadimos otra regla de la forma:

"rewrite/to_id2'" forall a. id2 a = id2' a 

y verá esta salida:

$ ghc -c foo.hs 
Rule fired: rewrite/to_id2' 
Rule fired: rewrite/to_id2' 
Rule fired: rewrite/to1' 
Rule fired: rewrite/ez 

La nueva norma está disparando en lugar de la op clase, lo que permite rewrite/to1' para simplificar la expresión. Curiosamente, no importa si la nueva regla aparece por encima o por debajo de rewrite/to1 en la lista de REGLAS.

No sé por qué su regla id2 (id2 a) no concuerda, mientras que id2 a lo hace. Parece que debe coincidir (de acuerdo con -dverbose-core2core), pero no lo es. Todavía sospecho un error de precedencia GHC de algún tipo, aunque también veo el mismo comportamiento con ghc-7.4.1, por lo que no es 4397.

+1

Acabo de instalar la versión más reciente de GHC - versión 7.4.1 y ahora obtengo el mismo resultado que antes. Además, sí, me doy cuenta de que estas reglas no influyen en la salida: acabo de hacer este caso de prueba para aislar el problema que estaba obteniendo en un ejemplo mucho más complicado. Además, creo que la precedencia está funcionando correctamente aquí ... simplemente mirando la salida realmente parece que todas mis reglas se están intentando antes de que aparezcan. – Akh

+0

¿Cómo está determinando exactamente que se intentaron sus reglas? No conozco ninguna forma de hacer que GHC muestre reglas que no se aplican, o qué regla se usa en el caso de múltiples coincidencias. Lo mejor que puede hacer es verificar lo que realmente se dispara, que en este caso es la regla de clase op. –

+0

Si cambia el programa para que el método de instancia devuelva algo así como un error, es decir, algo diferente al 'RDUnit' que la regla de reescritura debería dejarle, el optimizador le deja el valor del error en el ejemplo' testThing2'. Creo que este programa de ejemplo simplemente se redujo demasiado para mostrar el problema más claramente. – Anthony

Cuestiones relacionadas