2011-02-16 8 views
13

Sé de the documentation for -XUndecidableInstances, pero pensé que pediría una explicación.¿Cuándo es seguro IndecisibleInstances? Algunas preguntas generales con respecto a la extensión de GHC

Supongamos que tengo dos clases de tipos múltiples parámetros (se permiten con -XMultiParamTypeClasses)

class Foo a b 
class Goo a b 

Ahora, supongamos que tengo una parametrizado tipo de datos

data Bar a b 

que quiero hacer una instancia de Foo cuando uno de sus parámetros es parte de una instancia de Goo. No estoy seguro de la frase anterior utiliza una terminología exacta, así que esto es lo que quiero escribir:

instance (Goo c d) => Foo d (Bar a d) 

que no se me permite sin la extensión UndecidableInstances. ¿Estoy en lo cierto al pensar que esto se debe a que la instancia no hace referencia al tipo c?

¿Debo ...

  1. Solamente es necesario activar la extensión? ¿Puede alguien explicar en qué tipo de problemas me puede meter?
  2. Agregue otro parámetro a Foo, de modo que la última declaración de instancia se convierta en algo así como Foo c d (Bar a d)? Un problema con esto es que podría tener otras instancias de Foo que nunca hacen referencia a ningún "parámetro de tipo cuarto" (es decir, hay instancias del formulario instance Foo A B en partes no relacionadas de mi código), por lo que se romperían. Prefiero arreglar mi instancia, no mi clase.
  3. ¿Crear una nueva clase FooGoo con suficientes parámetros? Sentiría que me repito en ese caso, pero al menos no rompería las clases no relacionadas.

¿Alguien tiene alguna palabra de sabiduría?

Respuesta

10

¿Estoy en lo cierto al pensar que esto se debe a que la instancia no se refiere al tipo c?

Sí, el código no se adhiere a (de here):

Para cada afirmación en el contexto: Ninguna variable tipo tiene más apariciones en la afirmación de que en la cabeza

En general, debe estar seguro a menos que agregue otras instancias que, juntas, formarían un bucle. Las cosas solo se ponen realmente peludas (y dependientes del compilador) cuando se trata de OverlappingInstances, y caen en el mal cuando vas IncoherentInstances.

Sin saber más sobre lo que está tratando de lograr es difícil dar un consejo sobre el diseño de sonido, pero lo primero que debe verificar es si realmente necesita tener c como parámetro para Goo. Usted puede ser capaz de hacer expresar lo que quiere lograr de esta manera:

class Goo d where 
    bar :: d c -> Int 
    baz :: Quux c => d c -> Int 
+0

Gracias. Esto trae cierto grado de aclaración. – gspr

+0

+1 para describir 'IncoherentInstances' como malvado. –

+2

Creo que la restricción 'Goo cd' haría la instancia' Foo d (Bar ad) 'inutilizable a menos que' Goo' tenga una dependencia funcional 'd -> c' - de lo contrario, ¿cómo decide el compilador qué instancia de' Goo' ¿usar? Si todas las instancias 'Goo' tienen' c' como una variable de tipo que no aparece en 'd', entonces la sugerencia de @barsoap para eliminar ese tipo de parámetro es el camino a seguir. – mokus

Cuestiones relacionadas